Skip to content

Commit

Permalink
Merge pull request #20 from AthennaIO/develop
Browse files Browse the repository at this point in the history
Add test and make:test commands
  • Loading branch information
jlenon7 authored Jun 18, 2022
2 parents d6ebd69 + 067811b commit ac2a23c
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 5 deletions.
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.1.9",
"version": "1.2.0",
"description": "The Athenna CLI application. Built on top of commander.",
"license": "MIT",
"author": "João Lenon <[email protected]>",
Expand Down
68 changes: 68 additions & 0 deletions src/Commands/Make/Test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @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 { Path } from '@secjs/utils'
import { Artisan, Command } from '#src/index'
import { TemplateHelper } from '#src/Helpers/TemplateHelper'

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

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

/**
* Set additional flags in the commander instance.
* This method is executed when registering your command.
*
* @param {import('commander').Command} commander
* @return {import('commander').Command}
*/
addFlags(commander) {
return commander
.option('-u, --unit', 'Create the test inside unit folder.', false)
.option('--no-lint', 'Do not run eslint in the facade.', true)
}

/**
* Execute the console command.
*
* @param {string} name
* @param {any} options
* @return {Promise<void>}
*/
async handle(name, options) {
const resource = 'Test'
let subPath = Path.tests('E2E')

if (options.unit) {
subPath = Path.tests('Unit')
}

this.simpleLog(
`[ MAKING ${resource.toUpperCase()} ]\n`,
'rmNewLineStart',
'bold',
'green',
)

const file = await TemplateHelper.getResourceFile(name, resource, subPath)

this.success(`${resource} ({yellow} "${file.name}") successfully created.`)

if (options.lint) {
await Artisan.call(`eslint:fix ${file.path} --resource ${resource}`)
}
}
}
80 changes: 80 additions & 0 deletions src/Commands/Test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* @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 { Path } from '@secjs/utils'

import { Command } from '#src/index'

export class Test extends Command {
/**
* The name and signature of the console command.
*/
signature = 'test'

/**
* The console command description.
*/
description = 'Run the tests of Athenna application.'

/**
* Set additional flags in the commander instance.
* This method is executed when registering your command.
*
* @param {import('commander').Command} commander
* @return {import('commander').Command}
*/
addFlags(commander) {
return commander
.option('--c8-args', 'Arguments for c8 cli if needed.', null)
.option('--japa-args', 'Arguments for japa cli if needed.', null)
.option('--coverage', 'Coverage the code lines using c8 library.', false)
.option('--debug', 'Enable debug mode to see more logs.', false)
.option('--unit', 'Run unit tests.', false)
.option('--e2e', 'Run e2e tests.', false)
}

/**
* Execute the console command.
*
* @params {any} options
* @return {Promise<void>}
*/
async handle(options) {
process.env.BOOT_LOGS = 'false'
let command = ''

if (options.coverage) {
command = command.concat(`${Path.bin('c8')} `)

if (options.c8Args) {
command = command.concat(options.c8Args, ' ')
}
}

if (options.debug) {
command = command.concat(`${Path.bin('cross-env')} DEBUG=api:* && `)
}

command = command.concat(`node ${Path.tests('main.js')} `)

if (options.unit) {
command = command.concat('Unit ')
}

if (options.e2e) {
command = command.concat('E2E ')
}

if (options.japaArgs) {
command = command.concat(options.japaArgs, ' ')
}

await this.execCommand(command)
}
}
2 changes: 2 additions & 0 deletions src/Helpers/ArtisanLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ export class ArtisanLoader {
*/
static loadConsole() {
return [
import('#src/Commands/Test'),
import('#src/Commands/List'),
import('#src/Commands/Serve'),
import('#src/Commands/Eslint/Fix'),
import('#src/Commands/Make/Test'),
import('#src/Commands/Make/Facade'),
import('#src/Commands/Make/Service'),
import('#src/Commands/Make/Command'),
Expand Down
11 changes: 9 additions & 2 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,9 @@ export class ArtisanImpl {
* Call any command from Artisan.
*
* @param {string} command
* @return Promise<void>
* @return Promise<Commander>
*/
call(command: string): Promise<void>
call(command: string): Promise<Commander>

/**
* List all commands with description.
Expand Down Expand Up @@ -305,6 +305,13 @@ export class ArtisanImpl {
*/
getCommander(): Commander

/**
* Set the commander instance of Artisan.
*
* @return {import('commander').Command}
*/
setCommander(commander: Commander): void

/**
* Register the command inside commander instance.
*
Expand Down
14 changes: 12 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ export class ArtisanImpl {
* Call any command from Artisan.
*
* @param {string} command
* @return Promise<void>
* @return Promise<Command>
*/
async call(command) {
await this.#commander.parseAsync([
return this.#commander.parseAsync([
'node', // This will be ignored by commander
'artisan', // This will be ignored by commander
...command.split(' '),
Expand Down Expand Up @@ -146,6 +146,16 @@ export class ArtisanImpl {
return this.#commander
}

/**
* Set the commander instance of Artisan.
*
* @param {import('commander').Command} commander
* @return {void}
*/
setCommander(commander) {
this.#commander = commander
}

/**
* Register the command inside commander instance.
*
Expand Down
7 changes: 7 additions & 0 deletions templates/__name__Test.js.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { test } from '@japa/runner'

test.group('<%= namePascal %>Test', () => {
test('should be able to run tests', async ({ assert }) => {
assert.equal(2 + 2, 4)
})
})
67 changes: 67 additions & 0 deletions tests/Unit/Commands/Make/TestTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @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 { test } from '@japa/runner'
import { Config, File, Folder, Path } from '@secjs/utils'

import { Artisan } from '#src/index'
import { Kernel } from '#tests/Stubs/app/Console/Kernel'
import { ArtisanProvider } from '#src/Providers/ArtisanProvider'
import { LoggerProvider } from '@athenna/logger/providers/LoggerProvider'

test.group('MakeTestTest', group => {
group.each.setup(async () => {
await new Folder(Path.stubs('app')).copy(Path.app())
await new Folder(Path.stubs('config')).copy(Path.config())

await new Config().safeLoad(Path.config('app.js'))
await new Config().safeLoad(Path.config('logging.js'))

new LoggerProvider().register()
new ArtisanProvider().register()

const kernel = new Kernel()

await kernel.registerErrorHandler()
await kernel.registerCommands()
})

group.each.teardown(async () => {
await Folder.safeRemove(Path.app())
await Folder.safeRemove(Path.config())
await Folder.safeRemove(Path.providers())
})

test('should be able to create a test file', async ({ assert }) => {
await Artisan.call('make:test FeatureTest')

const path = Path.tests('E2E/FeatureTest.js')

assert.isTrue(await File.exists(path))

await Folder.safeRemove(Path.tests('E2E'))
}).timeout(60000)

test('should be able to create a unit test file', async ({ assert }) => {
await Artisan.call('make:test --unit UnitTest')

const path = Path.tests('Unit/UnitTest.js')

assert.isTrue(await File.exists(path))

await File.safeRemove(path)
}).timeout(60000)

test('should throw an error when the file already exists', async ({ assert }) => {
await Artisan.call('make:test TestTest')
await Artisan.call('make:test TestTest')

await Folder.safeRemove(Path.tests('E2E'))
}).timeout(60000)
})

0 comments on commit ac2a23c

Please sign in to comment.