Skip to content

Commit

Permalink
Merge pull request #9 from AthennaIO/develop
Browse files Browse the repository at this point in the history
feat: add make:exception command
  • Loading branch information
jlenon7 authored Apr 23, 2022
2 parents baf5a5f + 6819fa6 commit cf8c9ac
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@athenna/artisan",
"version": "1.0.9",
"version": "1.1.0",
"description": "",
"license": "MIT",
"author": "João Lenon <[email protected]>",
Expand Down
91 changes: 91 additions & 0 deletions src/Commands/Make/Exception.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* @athenna/artisan
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { parse } from 'path'
import { existsSync } from 'fs'
import { File, Path } from '@secjs/utils'
import { Artisan } from 'src/Facades/Artisan'
import { Command } from 'src/Commands/Command'
import { Commander } from 'src/Contracts/Commander'
import { TemplateHelper } from 'src/Utils/TemplateHelper'

export class Exception extends Command {
/**
* The name and signature of the console command.
*/
protected signature = 'make:exception <name>'

/**
* The console command description.
*/
protected description = 'Make a new exception file.'

/**
* Set additional flags in the commander instance.
* This method is executed when registering your command.
*
* @return {void}
*/
public addFlags(commander: Commander): Commander {
return commander
.option(
'-e, --extension <extension>',
'Current extension available: ts',
'ts',
)
.option('--no-lint', 'Do not run eslint in the exception', true)
}

/**
* Execute the console command.
*
* @return {Promise<void>}
*/
async handle(name: string, options: any): Promise<void> {
this.simpleLog('[ MAKING EXCEPTION ]', 'rmNewLineStart', 'bold', 'green')

name = TemplateHelper.normalizeName(name, 'Exception')
const template = TemplateHelper.getTemplate('__name__Exception', options)

if (!template) {
this.error(
`Template for extension ({yellow} "${options.extension}") has not been found.`,
)

return
}

const replacedName = TemplateHelper.replaceTemplateName(name, template.base)
const path = Path.app(`Exceptions/${replacedName}`)
const content = TemplateHelper.replaceTemplateValues(
name,
template.getContentSync(),
)

if (existsSync(path)) {
this.error(
`The exception ({yellow} "${
parse(path).name
}") already exists. Try using another name.`,
)

return
}

const exception = await new File(path, content).create()

this.success(
`Exception ({yellow} "${exception.name}") successfully created.`,
)

if (options.lint) {
await Artisan.call(`eslint:fix ${exception.path} --resource Exception`)
}
}
}
29 changes: 29 additions & 0 deletions templates/__name__Exception.ts.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Exception } from '@athenna/core'

/*
|--------------------------------------------------------------------------
| Exception
|--------------------------------------------------------------------------
|
| The Exception class imported from `@athenna/core` allows defining
| a status code, error code and help for every exception.
|
| @example
| new <%= namePascal %>Exception('message', 500, 'E_RUNTIME_EXCEPTION', 'Restart computer.')
|
*/

export class <%= namePascal %>Exception extends Exception {
/**
* Return a new instance of <%= namePascal %>Exception.
*
* @param message
* @param statusCode
* @param code
* @param help
* @return <%= namePascal %>Exception
*/
public constructor(message?: string, statusCode?: number, code?: string, help?: string) {
super(message, statusCode, code, help)
}
}
1 change: 1 addition & 0 deletions tests/Stubs/Kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class Kernel extends ConsoleKernel {
import('src/Commands/Make/Command'),
import('src/Commands/Make/Service'),
import('src/Commands/Make/Provider'),
import('src/Commands/Make/Exception'),
import('src/Commands/Make/Middleware'),
import('src/Commands/Make/Controller'),
]
Expand Down
47 changes: 47 additions & 0 deletions tests/Unit/Commands/Make/ExceptionTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @athenna/artisan
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import '@athenna/ioc'

import { existsSync } from 'fs'
import { Config } from '@athenna/config'
import { Folder, Path } from '@secjs/utils'
import { Kernel } from 'tests/Stubs/Kernel'
import { Artisan } from 'src/Facades/Artisan'
import { ArtisanProvider } from 'src/Providers/ArtisanProvider'
import { LoggerProvider } from '@athenna/logger/src/Providers/LoggerProvider'

describe('\n MakeExceptionTest', () => {
beforeEach(async () => {
new Folder(Path.tests('Stubs/config')).loadSync().copySync(Path.config())

await Config.load()
new LoggerProvider().register()
new ArtisanProvider().register()
await new Kernel().registerCommands()
})

it('should be able to create a exception file', async () => {
await Artisan.call('make:exception TestException')

const path = Path.app('Exceptions/TestException.ts')

expect(existsSync(path)).toBe(true)
}, 60000)

it('should throw an error when the file already exists', async () => {
await Artisan.call('make:exception TestException -e ts')
await Artisan.call('make:exception TestException -e ts')
}, 60000)

afterEach(async () => {
await Folder.safeRemove(Path.config())
await Folder.safeRemove(Path.app())
})
})

0 comments on commit cf8c9ac

Please sign in to comment.