From 6da3fcf60e5b735300719614bf83cd64a139d562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Lenon?= Date: Wed, 24 Nov 2021 12:23:27 -0300 Subject: [PATCH] feat: Remove useless functions and add global tests --- .gitignore | 2 + README.md | 125 ++----------- index.ts | 5 - src/Classes/File.ts | 35 +++- src/Classes/Folder.ts | 28 ++- src/Classes/Path.ts | 2 +- src/Functions/createFileOfSize.ts | 33 ---- src/Functions/dirSize.ts | 27 --- src/Functions/fileExists.ts | 17 -- src/Functions/formatBytes.ts | 2 +- src/Functions/getFiles.ts | 28 --- src/Functions/getFolders.ts | 48 ----- src/Functions/pathPattern.ts | 23 --- src/Functions/unset.ts | 2 +- src/utils/global.ts | 105 ++++++++++- tests/Classes/file.spec.ts | 5 +- tests/Classes/folder.spec.ts | 15 +- tests/Classes/path.spec.ts | 9 + tests/Functions/createFileOfSize.spec.ts | 24 --- tests/Functions/fileExists.spec.ts | 12 -- tests/Functions/getFiles.spec.ts | 9 - tests/Functions/getFolders.spec.ts | 19 -- tests/Functions/pathPattern.spec.ts | 23 --- tests/global/file.spec.ts | 213 +++++++++++++++++++++++ tests/global/folder.spec.ts | 175 +++++++++++++++++++ tests/global/path.spec.ts | 65 +++++++ tsconfig.json | 3 +- 27 files changed, 636 insertions(+), 418 deletions(-) delete mode 100644 src/Functions/createFileOfSize.ts delete mode 100644 src/Functions/dirSize.ts delete mode 100644 src/Functions/fileExists.ts delete mode 100644 src/Functions/getFiles.ts delete mode 100644 src/Functions/getFolders.ts delete mode 100644 src/Functions/pathPattern.ts delete mode 100644 tests/Functions/createFileOfSize.spec.ts delete mode 100644 tests/Functions/fileExists.spec.ts delete mode 100644 tests/Functions/getFiles.spec.ts delete mode 100644 tests/Functions/getFolders.spec.ts delete mode 100644 tests/Functions/pathPattern.spec.ts create mode 100644 tests/global/file.spec.ts create mode 100644 tests/global/folder.spec.ts create mode 100644 tests/global/path.spec.ts diff --git a/.gitignore b/.gitignore index 859a7ee..21697a9 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,6 @@ build # testing files generated here file-class-test +file-class-global-test folder-class-test +folder-class-global-test diff --git a/README.md b/README.md index 8baf192..3c95a5e 100644 --- a/README.md +++ b/README.md @@ -389,48 +389,7 @@ const decimals = 4 formatBytes(bytes, decimals) // Example: 1.0932 GB ``` -### createFileOfSize - -> Create a file in determined size. Good for testing. - -```ts -import { createFileOfSize } from '@secjs/utils' - -createFileOfSize('path/to/file', 1024*1024*1024) -``` - -### dirSize - -> Get the size of the directory without recursive going inside sub folders. - -```ts -import { dirSize } from '@secjs/utils' - -dirSize('path/to/directory') // The size in bytes -``` - -### pathPattern - -> Transform all route paths to the same pattern. - -```js -import { pathPattern } from '@secjs/utils' - -pathPattern('/users/:id/') // returns /users/:id -pathPattern('clients/') // returns /clients -pathPattern('/api/v2') // returns /api/v2 -pathPattern('/api/v3/') // returns /api/v3 - -pathPattern(['/api/v1/', 'api/v2', 'api/v3/', '/api/v4']) - -// returns -// [ -// '/api/v1', -// '/api/v2', -// '/api/v3', -// '/api/v4' -// ] -``` +--- ### getBranch @@ -442,28 +401,7 @@ import { getBranch } from '@secjs/utils' await getBranch() // master || Not a repository ``` -### pathPattern - -> Transform all route paths to the same pattern. - -```js -import { pathPattern } from '@secjs/utils' - -pathPattern('/users/:id/') // returns /users/:id -pathPattern('clients/') // returns /clients -pathPattern('/api/v2') // returns /api/v2 -pathPattern('/api/v3/') // returns /api/v3 - -pathPattern(['/api/v1/', 'api/v2', 'api/v3/', '/api/v4']) - -// returns -// [ -// '/api/v1', -// '/api/v2', -// '/api/v3', -// '/api/v4' -// ] -``` +--- ### download @@ -484,53 +422,6 @@ import { download } from '@secjs/utils' --- -### getFiles - -> Get all files inside a path and files inside folders if needed - -```js -import { getFiles } from '@secjs/utils' - -const iterateFolders = false -for await (const file of getFiles('any/path', iterateFolders)) { - console.log(file) // /home/path/to/your/file -} -``` - -### getFolders - -> Get all folders inside a path and files if needed. - -```js -import { getFolders } from '@secjs/utils' - -const withFiles = true -const directory = await getFolders('some/path', withFiles) - -// { -// path: '/home/some/path', -// files: ['/home/some/path/file.ts'], -// folders: [{ -// path: '/home/some/path/folder', -// files: ['/home/some/path/file.ts'], -// folders: [] -// }] as IDirectory[] -// } as IDirectory -``` - -### fileExists - -> Return true if file exists or false - -```js -import { fileExists } from '@secjs/utils' - -// Just abstracting the error that node throws -// if file does not exist - -console.log(fileExists('path/to/file')) // true or false -``` - ### observeChanges > Use observeChanges to observe changes in the value of an object @@ -555,6 +446,8 @@ data.name = 'João' // Name changed to: João { value: 'args are the same second parameter of doSomething function' } ``` +--- + ### removeDuplicated > Use removeDuplicated to remove duplicated values from an Array @@ -567,6 +460,8 @@ const array = [1, 1, 2, 4, 4] console.log(removeDuplicated(array)) // [1, 2, 4] ``` +--- + ### randomColor > Use randomColor to generate a random Hexadecimal color @@ -577,9 +472,11 @@ import { randomColor } from '@secjs/utils' console.log(randomColor()) // #7059c1 ``` +--- + ### isArrayOfObjects -> Use isArrayOfObjects to verify if all values inside of the array are objects +> Use isArrayOfObjects to verify if all values inside the array are objects ```js import { isArrayOfObjects } from '@secjs/utils' @@ -597,9 +494,11 @@ console.log(isArrayOfObjects(array3)) // true console.log(isArrayOfObjects(fakeArray)) // false ``` +--- + ### urlify -> Use urlify to inject some URL of a string inside a HTML Link +> Use urlify to inject some URL of a string inside an HTML Link ```js import { urlify } from '@secjs/utils' diff --git a/index.ts b/index.ts index 4120fdf..b11fdd0 100644 --- a/index.ts +++ b/index.ts @@ -20,15 +20,10 @@ export * from './src/Functions/download' export * from './src/Functions/fillable' export * from './src/Functions/kmRadius' export * from './src/Functions/paginate' -export * from './src/Functions/getFiles' export * from './src/Functions/scheduler' export * from './src/Functions/getBranch' -export * from './src/Functions/getFolders' -export * from './src/Functions/fileExists' -export * from './src/Functions/pathPattern' export * from './src/Functions/getCommitId' export * from './src/Functions/randomColor' export * from './src/Functions/observeChanges' export * from './src/Functions/removeDuplicated' export * from './src/Functions/isArrayOfObjects' -export * from './src/Functions/createFileOfSize' diff --git a/src/Classes/File.ts b/src/Classes/File.ts index 006a6a7..5774984 100644 --- a/src/Classes/File.ts +++ b/src/Classes/File.ts @@ -1,4 +1,4 @@ -/* +/** * @secjs/utils * * (c) João Lenon @@ -48,13 +48,28 @@ export interface FileJsonContract { } export class File { - constructor(path: string, content: Buffer | null = null) { - const { ext, dir, name, base, mime } = File.parsePath(path) + static async createFileOfSize(filePath: string, size: number) { + const { dir, path } = File.parsePath(filePath) + + await promises.mkdir(dir, { recursive: true }) + + return new Promise((resolve, reject) => { + const writable = createWriteStream(path) + + writable.write(Buffer.alloc(Math.max(0, size - 2), 'l')) + + writable.end(() => resolve(this)) + writable.on('error', err => reject(err)) + }) + } + + constructor(filePath: string, content: Buffer | null = null) { + const { ext, dir, name, base, mime, path } = File.parsePath(filePath) this._originalDir = dir this._originalName = name this._originalBase = base - this._originalPath = this._originalDir + '/' + this._originalBase + this._originalPath = path this._originalFileExists = existsSync(this._originalPath) this._fileExists = this._originalFileExists this._content = content @@ -130,7 +145,7 @@ export class File { }) } - loadSync(options?: { withContent: boolean }) { + loadSync(options?: { withContent?: boolean }) { options = Object.assign({}, { withContent: true }, options) if (this._content && this._fileExists) @@ -162,7 +177,7 @@ export class File { return this } - async load(options?: { withContent: boolean }): Promise { + async load(options?: { withContent?: boolean }): Promise { options = Object.assign({}, { withContent: true }, options) if (this._content && this._fileExists) { @@ -287,8 +302,10 @@ export class File { this._path = this._dir + '/' + this._base } - private static parsePath(path: string) { - const { base, dir, root } = parse(isAbsolute(path) ? path : Path.pwd(path)) + private static parsePath(filePath: string) { + const { base, dir, root } = parse( + isAbsolute(filePath) ? filePath : Path.pwd(filePath), + ) const baseArray = base.split('.') @@ -300,7 +317,7 @@ export class File { }, '') const mime = lookup(dir + '/' + base) - return { ext, dir, name, root, base, mime } + return { ext, dir, name, root, base, mime, path: dir + '/' + base } } private _dir?: string diff --git a/src/Classes/Folder.ts b/src/Classes/Folder.ts index 4e609ba..84adba4 100644 --- a/src/Classes/Folder.ts +++ b/src/Classes/Folder.ts @@ -1,4 +1,4 @@ -/* +/** * @secjs/utils * * (c) João Lenon @@ -22,7 +22,7 @@ import { import { File } from './File' import { Path } from './Path' import { randomBytes } from 'crypto' -import { isAbsolute, parse, resolve } from 'path' +import { isAbsolute, join, parse, resolve } from 'path' import { formatBytes } from '../Functions/formatBytes' import { InternalServerException } from '@secjs/exceptions' @@ -45,12 +45,22 @@ export interface FolderJsonContract { } export class Folder { - constructor(path: string) { - const { dir, name } = Folder.parsePath(path) + static async folderSize(folderPath: string): Promise { + const files = await promises.readdir(folderPath) + const stats = files.map(file => promises.stat(join(folderPath, file))) + + return (await Promise.all(stats)).reduce( + (accumulator, { size }) => accumulator + size, + 0, + ) + } + + constructor(folderPath: string) { + const { dir, name, path } = Folder.parsePath(folderPath) this._originalDir = dir this._originalName = name - this._originalPath = this._originalDir + '/' + this._originalName + this._originalPath = path this._originalFolderExists = existsSync(this._originalPath) this._folderExists = this._originalFolderExists @@ -298,10 +308,12 @@ export class Folder { this._path = this._dir + '/' + this._name } - private static parsePath(path: string) { - const { dir, name } = parse(isAbsolute(path) ? path : Path.pwd(path)) + private static parsePath(folderPath: string) { + const { dir, name } = parse( + isAbsolute(folderPath) ? folderPath : Path.pwd(folderPath), + ) - return { dir, name } + return { dir, name, path: dir + '/' + name } } private loadSubSync( diff --git a/src/Classes/Path.ts b/src/Classes/Path.ts index f3388a9..5f6f78e 100644 --- a/src/Classes/Path.ts +++ b/src/Classes/Path.ts @@ -1,4 +1,4 @@ -/* +/** * @secjs/utils * * (c) João Lenon diff --git a/src/Functions/createFileOfSize.ts b/src/Functions/createFileOfSize.ts deleted file mode 100644 index fb3fc17..0000000 --- a/src/Functions/createFileOfSize.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * @secjs/utils - * - * (c) João Lenon - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -import { closeSync, mkdirSync, openSync, writeSync } from 'fs' - -/** - * createFileOfSize creates a file with any size - * - * @param fileName - the path to the file - * @param size - the size of the file to be created - * @return void - */ -export function createFileOfSize(fileName: string, size: number) { - const fileNameArray = fileName.split('/') - - fileNameArray.pop() - - const dir = fileNameArray.join('/') - - mkdirSync(dir, { recursive: true }) - - const fh = openSync(fileName, 'w') - - writeSync(fh, Buffer.alloc(Math.max(0, size - 2), 'l')) - - closeSync(fh) -} diff --git a/src/Functions/dirSize.ts b/src/Functions/dirSize.ts deleted file mode 100644 index ee72ec4..0000000 --- a/src/Functions/dirSize.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * @secjs/utils - * - * (c) João Lenon - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -import { join } from 'path' -import { readdir, stat } from 'fs/promises' - -/** - * dirSize returns the size of the directory without recursively going through it - * - * @param path - the directory path - * @return size - the size of the directory in bytes - */ -export async function dirSize(path: string): Promise { - const files = await readdir(path) - const stats = files.map(file => stat(join(path, file))) - - return (await Promise.all(stats)).reduce( - (accumulator, { size }) => accumulator + size, - 0, - ) -} diff --git a/src/Functions/fileExists.ts b/src/Functions/fileExists.ts deleted file mode 100644 index ee1a9b5..0000000 --- a/src/Functions/fileExists.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { promises } from 'fs' - -/** - * Verify if file exists on certain path - * - * @param path The path of the file - * @return Boolean value - */ -export async function fileExists(path: string): Promise { - try { - await promises.access(path) - - return true - } catch (error) { - return false - } -} diff --git a/src/Functions/formatBytes.ts b/src/Functions/formatBytes.ts index 63363d6..c84258a 100644 --- a/src/Functions/formatBytes.ts +++ b/src/Functions/formatBytes.ts @@ -1,4 +1,4 @@ -/* +/** * @secjs/utils * * (c) João Lenon diff --git a/src/Functions/getFiles.ts b/src/Functions/getFiles.ts deleted file mode 100644 index 912ea4d..0000000 --- a/src/Functions/getFiles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { resolve } from 'path' -import { promises } from 'fs' - -/** - * Return all files of a directory and sub directories - * - * @param dir The directory - * @param iterateFolders If need to get files inside sub directories by default true - * @param buffer Return the buffer of the file by default false - * @yield files path - */ -export async function* getFiles( - dir: string, - iterateFolders = true, - buffer = false, -): any { - const dirents = await promises.readdir(dir, { withFileTypes: true }) - - for (const dirent of dirents) { - const res = resolve(dir, dirent.name) - - if (dirent.isDirectory() && iterateFolders) { - yield* getFiles(res) - } else { - yield buffer ? Buffer.from(res) : res - } - } -} diff --git a/src/Functions/getFolders.ts b/src/Functions/getFolders.ts deleted file mode 100644 index a9ca1e0..0000000 --- a/src/Functions/getFolders.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { promises } from 'fs' -import { resolve, basename } from 'path' -import { DirectoryContract } from '@secjs/contracts' - -/** - * Return all folders of a directory and files inside - * - * @param dir The directory - * @param withFiles If need to get files inside folders by default false - * @param buffer Return the buffer of the file by default false - * @param fullPath Return the full path of folder or archive by default false - * @return The directory root with sub folders and files when withFiles true - */ -export async function getFolders( - dir: string, - withFiles = false, - buffer = false, - fullPath = false, -): Promise { - const dirents = await promises.readdir(dir, { withFileTypes: true }) - - const directory = { - path: fullPath ? resolve(dir) : basename(resolve(dir)), - files: [], - folders: [], - } - - for (const dirent of dirents) { - const res = resolve(dir, dirent.name) - - if (dirent.isDirectory()) { - directory.folders.push(await getFolders(res, withFiles, buffer, fullPath)) - - continue - } - - if (dirent.isFile() && withFiles) { - directory.files.push({ - name: fullPath ? res : basename(res), - value: buffer - ? Buffer.from(res) - : await promises.readFile(res, 'utf-8'), - }) - } - } - - return directory -} diff --git a/src/Functions/pathPattern.ts b/src/Functions/pathPattern.ts deleted file mode 100644 index 334dceb..0000000 --- a/src/Functions/pathPattern.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Transform path or array of paths to pattern /api/v1 - * - * @param path The path to be transformed - * @return path string|string[] of paths transformed - */ -export function pathPattern(path: string | string[]): string | string[] { - if (path === '/') return path - - const pattern = (path: string) => { - const pathArray = path.split('/') - - if (pathArray[0] !== '/') pathArray.unshift('') - - return `/${pathArray.filter(p => p !== '').join('/')}` - } - - if (typeof path !== 'string') { - return path.map(p => pattern(p)) - } - - return pattern(path) -} diff --git a/src/Functions/unset.ts b/src/Functions/unset.ts index e365ea3..d79bf7b 100644 --- a/src/Functions/unset.ts +++ b/src/Functions/unset.ts @@ -1,4 +1,4 @@ -/* +/** * @secjs/utils * * (c) João Lenon diff --git a/src/utils/global.ts b/src/utils/global.ts index 2ae8acf..d18568f 100644 --- a/src/utils/global.ts +++ b/src/utils/global.ts @@ -1,9 +1,34 @@ +/** + * @secjs/utils + * + * (c) João Lenon + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + import { unset as unsetFn } from '../Functions/unset' import { Path as PathInstance } from '../Classes/Path' +import { Folder as FolderInstance, FolderJsonContract } from '../Classes/Folder' +import { File, File as FileInstance, FileJsonContract } from '../Classes/File' + +const _global = global as any + +// Classes +_global.Path = PathInstance +_global.File = FileInstance +_global.Folder = FolderInstance + +// Functions +_global.unset = unsetFn export {} +declare global {} + declare global { + function unset(object: any): void + class Path { static nodeCwdPath(): string static forceBuild(): typeof Path @@ -25,13 +50,79 @@ declare global { static forBuild(name: string): typeof Path static changeBuild(name: string): typeof Path } - function unset(object: any): void -} -const _global = global as any + class File { + static createFileOfSize(filePath: string, size: number): Promise + constructor(filePath: string, content?: Buffer | null) + toJSON(): FileJsonContract + createSync(): File + create(): Promise + loadSync(options?: { withContent?: boolean }): File + load(options?: { withContent?: boolean }): Promise + getContentSync(): Buffer + getContent(): Promise + removeSync(): File + remove(): Promise + get dir(): string + get name(): string + get base(): string + get path(): string + get content(): Buffer + get createdAt(): Date + get accessedAt(): Date + get modifiedAt(): Date + get fileSize(): string + get extension(): string + get originalDir(): string + get mime(): string + get originalName(): string + get originalBase(): string + get originalPath(): string + /** + * fileExists - If true means the file has been created or already exists + */ + get fileExists(): boolean + /** + * _originalFileExists - If true means the file already exists when creating the instance + */ + get originalFileExists(): boolean + } -// Classes -_global.Path = PathInstance + class Folder { + static folderSize(folderPath: string): Promise + constructor(folderPath: string) + toJSON(): FolderJsonContract + createSync(): Folder + create(): Promise + loadSync(options?: { withSub?: boolean; withFileContent?: boolean }) + load(options?: { + withSub?: boolean + withFileContent?: boolean + }): Promise -// Functions -_global.unset = unsetFn + removeSync(): Folder + remove(): Promise + getFilesByPattern(pattern: string, recursive?: boolean): File[] + getFoldersByPattern(pattern: string, recursive?: boolean): Folder[] + get dir(): string + get name(): string + get path(): string + get files(): File[] + get folders(): Folder[] + get createdAt(): Date + get accessedAt(): Date + get modifiedAt(): Date + get folderSize(): string + get originalDir(): string + get originalName(): string + get originalPath(): string + /** + * fileExists - If true means the file has been created or already exists + */ + get folderExists(): boolean + /** + * _originalFileExists - If true means the file already exists when creating the instance + */ + get originalFolderExists(): boolean + } +} diff --git a/tests/Classes/file.spec.ts b/tests/Classes/file.spec.ts index 60d9049..5cedabb 100644 --- a/tests/Classes/file.spec.ts +++ b/tests/Classes/file.spec.ts @@ -1,4 +1,4 @@ -/* +/** * @secjs/utils * * (c) João Lenon @@ -10,7 +10,6 @@ import { existsSync, promises } from 'fs' import { Path } from '../../src/Classes/Path' import { File } from '../../src/Classes/File' -import { createFileOfSize } from '../../src/Functions/createFileOfSize' describe('\n File Class', () => { let bigFile: File = null @@ -20,7 +19,7 @@ describe('\n File Class', () => { const nonexistentFilePath = Path.pwd('tests/file-class-test/non-existent.txt') beforeEach(async () => { - createFileOfSize(bigFilePath, 1024 * 1024 * 100) + await File.createFileOfSize(bigFilePath, 1024 * 1024 * 100) bigFile = new File(bigFilePath) nonexistentFile = new File(nonexistentFilePath, Buffer.from('Content')) diff --git a/tests/Classes/folder.spec.ts b/tests/Classes/folder.spec.ts index 57cc495..27e02f7 100644 --- a/tests/Classes/folder.spec.ts +++ b/tests/Classes/folder.spec.ts @@ -1,5 +1,5 @@ /* eslint-disable no-new */ -/* +/** * @secjs/utils * * (c) João Lenon @@ -11,9 +11,12 @@ import { existsSync, promises } from 'fs' import { Path } from '../../src/Classes/Path' import { Folder } from '../../src/Classes/Folder' -import { createFileOfSize } from '../../src/Functions/createFileOfSize' +import { File } from '../../src/Classes/File' describe('\n Folder Class', () => { + // 100 MB + const size = 1024 * 1024 * 100 + let bigFolder: Folder = null let nonexistentFolder: Folder = null @@ -21,12 +24,12 @@ describe('\n Folder Class', () => { const nonexistentFolderPath = Path.pwd('tests/folder-class-test/non-existent') beforeEach(async () => { - createFileOfSize(bigFolderPath + '/file.txt', 1024 * 1024 * 100) + await File.createFileOfSize(bigFolderPath + '/file.txt', size) bigFolder = new Folder(bigFolderPath) - createFileOfSize(bigFolderPath + '/hello/file.txt', 1024 * 1024 * 100) - createFileOfSize(bigFolderPath + '/hello/nice/file.txt', 1024 * 1024 * 100) + await File.createFileOfSize(bigFolderPath + '/hello/file.txt', size) + await File.createFileOfSize(bigFolderPath + '/hello/nice/file.txt', size) nonexistentFolder = new Folder(nonexistentFolderPath) }) @@ -153,7 +156,7 @@ describe('\n Folder Class', () => { it('should load all the files and subFolders with the files content', async () => { nonexistentFolder.createSync() - createFileOfSize(nonexistentFolder.path + '/file.txt', 1024 * 1024 * 100) + await File.createFileOfSize(nonexistentFolder.path + '/file.txt', size) nonexistentFolder.loadSync({ withFileContent: true }) diff --git a/tests/Classes/path.spec.ts b/tests/Classes/path.spec.ts index 3d9f034..b824174 100644 --- a/tests/Classes/path.spec.ts +++ b/tests/Classes/path.spec.ts @@ -1,3 +1,12 @@ +/** + * @secjs/utils + * + * (c) João Lenon + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + import { Path } from '../../src/Classes/Path' describe('\n Path Class', () => { diff --git a/tests/Functions/createFileOfSize.spec.ts b/tests/Functions/createFileOfSize.spec.ts deleted file mode 100644 index cc50c44..0000000 --- a/tests/Functions/createFileOfSize.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * @secjs/utils - * - * (c) João Lenon - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -import { readFileSync, rmSync } from 'fs' -import { createFileOfSize } from '../../src/Functions/createFileOfSize' - -describe('\n createFileOfSize Function', () => { - const filePath = process.cwd() + 'test.txt' - - it('should create a file from any size', async () => { - // 1 MB - createFileOfSize(filePath, 1024 * 1024) - - expect(readFileSync(filePath)).toBeTruthy() - }) - - afterAll(() => rmSync(filePath)) -}) diff --git a/tests/Functions/fileExists.spec.ts b/tests/Functions/fileExists.spec.ts deleted file mode 100644 index 2ee96f7..0000000 --- a/tests/Functions/fileExists.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import path from 'path' -import { fileExists } from '../../src/Functions/fileExists' - -describe('\n fileExists Function', () => { - it('should return true when the file exists and false when does not exist', async () => { - const filePath = path.resolve(__dirname, 'fileExists.spec.ts') - const wrongPath = path.resolve(__dirname, 'fileExists.spec.tsss') - - expect(await fileExists(filePath)).toBe(true) - expect(await fileExists(wrongPath)).toBe(false) - }) -}) diff --git a/tests/Functions/getFiles.spec.ts b/tests/Functions/getFiles.spec.ts deleted file mode 100644 index 4878475..0000000 --- a/tests/Functions/getFiles.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { getFiles } from '../../src/Functions/getFiles' - -describe('\n getFiles Function', () => { - it('should loop inside folders and files and return the path', async () => { - for await (const file of getFiles('tests')) { - expect(file).toBeTruthy() - } - }) -}) diff --git a/tests/Functions/getFolders.spec.ts b/tests/Functions/getFolders.spec.ts deleted file mode 100644 index bdc99fe..0000000 --- a/tests/Functions/getFolders.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { getFolders } from '../../src/Functions/getFolders' - -describe('\n getFolders Function', () => { - it('should loop inside folders and files and return the directory', async () => { - const directory = await getFolders('tests', true) - - expect(directory.path).toBeTruthy() - expect(directory.files).toBeTruthy() - expect(directory.folders).toBeTruthy() - }) - - it('should loop inside folders and files and return the directory with buffer', async () => { - const directory = await getFolders('tests', true, true) - - expect(directory.path).toBeTruthy() - expect(directory.files).toBeTruthy() - expect(directory.folders).toBeTruthy() - }) -}) diff --git a/tests/Functions/pathPattern.spec.ts b/tests/Functions/pathPattern.spec.ts deleted file mode 100644 index 6d9d4e2..0000000 --- a/tests/Functions/pathPattern.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { pathPattern } from '../../src/Functions/pathPattern' - -describe('\n pathPattern Function', () => { - it('should transform any path to the pattern /api/v1', async () => { - const path1 = '/users/:id/' - const path2 = 'clients/' - const path3 = '/api/v2' - const path4 = '/api/v3/' - - const paths = ['/api/v1/', 'api/v2', 'api/v3/', '/api/v4'] - - expect(pathPattern(path1)).toStrictEqual('/users/:id') - expect(pathPattern(path2)).toStrictEqual('/clients') - expect(pathPattern(path3)).toStrictEqual('/api/v2') - expect(pathPattern(path4)).toStrictEqual('/api/v3') - expect(pathPattern(paths)).toStrictEqual([ - '/api/v1', - '/api/v2', - '/api/v3', - '/api/v4', - ]) - }) -}) diff --git a/tests/global/file.spec.ts b/tests/global/file.spec.ts new file mode 100644 index 0000000..087bfc1 --- /dev/null +++ b/tests/global/file.spec.ts @@ -0,0 +1,213 @@ +/** + * @secjs/utils + * + * (c) João Lenon + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import '../../src/utils/global' + +import { existsSync, promises } from 'fs' + +describe('\n File Class Global', () => { + let bigFile: File = null + let nonexistentFile: File = null + + const bigFilePath = Path.pwd('tests/file-class-global-test/file.txt') + const nonexistentFilePath = Path.pwd( + 'tests/file-class-global-test/non-existent.txt', + ) + + beforeEach(async () => { + await File.createFileOfSize(bigFilePath, 1024 * 1024 * 100) + + bigFile = new File(bigFilePath) + nonexistentFile = new File(nonexistentFilePath, Buffer.from('Content')) + }) + + it('should generate an instance of a file, it existing or not', async () => { + expect(bigFile.path).toBe(bigFilePath) + expect(bigFile.mime).toBe('text/plain') + expect(bigFile.originalPath).toBe(bigFilePath) + expect(bigFile.originalFileExists).toBe(true) + expect(bigFile.dir).toBe(bigFilePath.replace('/file.txt', '')) + + expect(nonexistentFile.base).toBeTruthy() + expect(nonexistentFile.path).toBeTruthy() + expect(nonexistentFile.mime).toBe('text/plain') + expect(nonexistentFile.originalFileExists).toBe(false) + expect(nonexistentFile.originalPath).toBe(nonexistentFilePath) + expect(nonexistentFile.originalBase).toBe('non-existent.txt') + }) + + it('should create the file when it does not exist and throw errors if trying to create a file that already exists and load the files information', async () => { + try { + await bigFile.create() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('File already exists') + } + + try { + nonexistentFile.loadSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe( + 'File does not exist, use create method to create the file', + ) + } + + nonexistentFile.createSync() + + expect(nonexistentFile.fileExists).toBe(true) + expect(existsSync(nonexistentFile.path)).toBe(true) + expect(nonexistentFile.originalFileExists).toBe(false) + + // LOAD + + expect(bigFile.content).toBeFalsy() + await bigFile.load() + + expect(bigFile.content).toBeTruthy() + expect(bigFile.fileSize.includes('MB')).toBe(true) + + expect(nonexistentFile.content).toBeFalsy() + nonexistentFile.loadSync() + + expect(nonexistentFile.content).toBeTruthy() + expect(nonexistentFile.fileSize.includes('Bytes')).toBe(true) + }) + + it('should throw an internal server exception when trying to reload/recreate the file', async () => { + try { + await bigFile.create() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('File already exists') + } + + try { + await bigFile.load() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('File has been already loaded') + } + + try { + nonexistentFile.createSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('File already exists') + } + + try { + nonexistentFile.loadSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('File has been already loaded') + } + }) + + it('should be able to get the file information in JSON Format', async () => { + expect(bigFile.toJSON().name).toBeTruthy() + expect(nonexistentFile.toJSON().name).toBeTruthy() + }) + + it('should be able to get the file content', async () => { + expect(await bigFile.getContent()).toBeTruthy() + + try { + nonexistentFile.getContentSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe( + 'File does not exist, use create method to create the file', + ) + } + }) + + it('should remove the files and remove file stats from instance', async () => { + await bigFile.remove() + + expect(existsSync(bigFile.path)).toBe(false) + + nonexistentFile.createSync() + nonexistentFile.removeSync() + + expect(existsSync(nonexistentFile.path)).toBe(false) + + try { + await bigFile.create() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('Cannot create a file without content') + } + + try { + nonexistentFile.createSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('Cannot create a file without content') + } + }) + + it('should throw an internal server exception when trying to remove the file calling remove/removeSync again', async () => { + bigFile.removeSync() + + try { + bigFile.removeSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('File does not exist') + } + + try { + await nonexistentFile.remove() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('File does not exist') + } + }) + + it('should load the file but without content', async () => { + await bigFile.load({ withContent: false }) + + expect(bigFile.content).toBeFalsy() + + nonexistentFile.createSync().loadSync({ withContent: false }) + + expect(nonexistentFile.content).toBeFalsy() + }) + + afterEach(async () => { + await promises.rmdir(bigFile.dir, { recursive: true }) + await promises.rmdir(nonexistentFile.dir, { recursive: true }) + + unset(bigFile) + unset(nonexistentFile) + }) +}) diff --git a/tests/global/folder.spec.ts b/tests/global/folder.spec.ts new file mode 100644 index 0000000..8af1a31 --- /dev/null +++ b/tests/global/folder.spec.ts @@ -0,0 +1,175 @@ +/* eslint-disable no-new */ +/** + * @secjs/utils + * + * (c) João Lenon + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import '../../src/utils/global' + +import { existsSync, promises } from 'fs' + +describe('\n Folder Class Global', () => { + // 100 MB + const size = 1024 * 1024 * 100 + + let bigFolder: Folder = null + let nonexistentFolder: Folder = null + + const bigFolderPath = Path.pwd('tests/folder-class-global-test/big') + const nonexistentFolderPath = Path.pwd( + 'tests/folder-class-global-test/non-existent', + ) + + beforeEach(async () => { + await File.createFileOfSize(bigFolderPath + '/file.txt', size) + + bigFolder = new Folder(bigFolderPath) + + await File.createFileOfSize(bigFolderPath + '/hello/file.txt', size) + await File.createFileOfSize(bigFolderPath + '/hello/nice/file.txt', size) + + nonexistentFolder = new Folder(nonexistentFolderPath) + }) + + it('should generate an instance of a folder, it existing or not', async () => { + expect(bigFolder.path).toBe(bigFolderPath) + expect(bigFolder.folderExists).toBe(true) + expect(bigFolder.originalPath).toBe(bigFolderPath) + expect(bigFolder.originalFolderExists).toBe(true) + expect(bigFolder.dir).toBe(bigFolderPath.replace('/big', '')) + + expect(nonexistentFolder.path).toBeTruthy() + expect(nonexistentFolder.folderExists).toBe(false) + expect(nonexistentFolder.originalFolderExists).toBe(false) + expect(nonexistentFolder.originalPath).toBe(nonexistentFolderPath) + }) + + it('should create the folder when it does not exist and throw errors if trying to create a folder that already exists and load the subFiles/subFolders information', async () => { + try { + await bigFolder.create() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('Folder already exists') + } + + try { + nonexistentFolder.loadSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe( + 'Folder does not exist, use create method to create the folder', + ) + } + + nonexistentFolder.createSync() + + expect(nonexistentFolder.folderExists).toBe(true) + expect(existsSync(nonexistentFolder.path)).toBe(true) + expect(nonexistentFolder.originalFolderExists).toBe(false) + + // LOAD + + expect(bigFolder.files.length).toBe(0) + expect(bigFolder.folders.length).toBe(0) + await bigFolder.load() + + expect(bigFolder.files.length).toBeTruthy() + expect(bigFolder.folders.length).toBeTruthy() + expect(bigFolder.folderSize.includes('KB')).toBe(true) + + nonexistentFolder.loadSync() + + expect(nonexistentFolder.files.length).toBe(0) + expect(nonexistentFolder.folders.length).toBe(0) + expect(nonexistentFolder.folderSize.includes('KB')).toBe(true) + }) + + it('should throw an internal server exception when trying to reload/recreate the file', async () => { + try { + await bigFolder.create() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('Folder already exists') + } + + try { + await bigFolder.load() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('Folder has been already loaded') + } + + try { + nonexistentFolder.createSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('Folder already exists') + } + + try { + nonexistentFolder.loadSync() + } catch (error) { + expect(error.status).toBe(500) + expect(error.isSecJsException).toBe(true) + expect(error.name).toBe('InternalServerException') + expect(error.content).toBe('Folder has been already loaded') + } + }) + + it('should be able to get the file information in JSON Format', async () => { + expect(bigFolder.toJSON().name).toBeTruthy() + expect(nonexistentFolder.toJSON().name).toBeTruthy() + }) + + it('should get all files and folders that match the pattern', async () => { + const files = bigFolder + .loadSync() + .getFilesByPattern('tests/folder-class-global-test/**/*.txt', true) + + expect(files.length).toBe(3) + + files.forEach(file => expect(file.extension).toBe('.txt')) + + const folders = bigFolder.getFoldersByPattern( + 'tests/folder-class-global-test/big/*', + true, + ) + + expect(folders.length).toBe(2) + expect(folders[0].name).toBe('hello') + expect(folders[1].name).toBe('nice') + }) + + it('should load all the files and subFolders with the files content', async () => { + nonexistentFolder.createSync() + + await File.createFileOfSize(nonexistentFolder.path + '/file.txt', size) + + nonexistentFolder.loadSync({ withFileContent: true }) + + expect(nonexistentFolder.files[0].base).toBe('file.txt') + expect(nonexistentFolder.files[0].content).toBeTruthy() + }) + + afterEach(async () => { + await promises.rmdir(bigFolder.dir, { recursive: true }) + await promises.rmdir(nonexistentFolder.dir, { recursive: true }) + + unset(bigFolder) + unset(nonexistentFolder) + }) +}) diff --git a/tests/global/path.spec.ts b/tests/global/path.spec.ts new file mode 100644 index 0000000..23a3eda --- /dev/null +++ b/tests/global/path.spec.ts @@ -0,0 +1,65 @@ +/** + * @secjs/utils + * + * (c) João Lenon + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import '../../src/utils/global' + +describe('\n Path Class Global', () => { + it('should get application pwd path', () => { + const myMainPath = process.cwd() + const mySrcPath = myMainPath + '/src' + const mySrcAppPath = myMainPath + '/src/app' + + expect(Path.pwd()).toBe(myMainPath) + expect(Path.pwd('/src')).toBe(mySrcPath) + expect(Path.pwd('/src/')).toBe(mySrcPath) + expect(Path.pwd('///src///')).toBe(mySrcPath) + expect(Path.pwd('///src///app///')).toBe(mySrcAppPath) + }) + + it('should get application storage path', () => { + const myStoragePath = process.cwd() + '/storage' + const myStorageLogsPath = myStoragePath + '/logs' + + expect(Path.storage()).toBe(myStoragePath) + expect(Path.storage('logs')).toBe(myStorageLogsPath) + expect(Path.storage('///logs///')).toBe(myStorageLogsPath) + }) + + it('should get application views path', () => { + const myViewsPath = process.cwd() + '/resources/views' + const myViewsMailPath = myViewsPath + '/Mail' + + expect(Path.views()).toBe(myViewsPath) + expect(Path.views('Mail')).toBe(myViewsMailPath) + expect(Path.views('///Mail///')).toBe(myViewsMailPath) + }) + + it('should get node cwd path based on ts build folder validations', () => { + const myMainPath = process.cwd() + const myMainDistPath = process.cwd() + '/dist' + + expect(Path.forceBuild().nodeCwdPath()).toBe(myMainDistPath) + expect(Path.forBuild('build').nodeCwdPath()).toBe(myMainPath + '/build') + expect(Path.forceBuild().nodeCwdPath()).toBe(myMainDistPath) + expect(Path.forceBuild().changeBuild('/test').nodeCwdPath()).toBe( + myMainPath + '/test', + ) + + Path.changeBuild('/dist') + + process.env.NODE_ENV = 'testing' + expect(Path.nodeCwdPath()).toBe(myMainDistPath) + + process.env.NODE_ENV = 'ts-development' + expect(Path.nodeCwdPath()).toBe(myMainDistPath) + + process.env.NODE_ENV = 'production' + expect(Path.nodeCwdPath()).toBe(myMainPath) + }) +}) diff --git a/tsconfig.json b/tsconfig.json index 34fc863..a6863a1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "sourceMap": false, "allowJs": false, "strict": true, - "strictNullChecks": false + "strictNullChecks": false, + "lib": ["es2017"] }, "include": ["*.ts", "**/*.ts"], "exclude": ["node_modules", "build", "dist", "tests"]