-
-
Notifications
You must be signed in to change notification settings - Fork 622
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
867c0bf
commit ca12275
Showing
4 changed files
with
694 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/* | ||
* @adonisjs/core | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
import type { CommandOptions } from '../types/ace.js' | ||
import { BaseCommand, flags, args } from '../modules/ace/main.js' | ||
import { detectAssetsBundler, importAssembler, importTypeScript } from '../src/internal_helpers.js' | ||
|
||
/** | ||
* Test command is used to run tests with optional file watcher. Under the | ||
* hood, we run "bin/test.js" file. | ||
*/ | ||
export default class Test extends BaseCommand { | ||
static commandName = 'test' | ||
static description = 'Run tests along with the file watcher to re-run tests on file change' | ||
|
||
static options: CommandOptions = { | ||
allowUnknownFlags: true, | ||
staysAlive: true, | ||
} | ||
|
||
@args.spread({ | ||
description: 'Mention suite names to run tests for selected suites', | ||
required: false, | ||
}) | ||
declare suites?: string[] | ||
|
||
@flags.array({ description: 'Filter tests by the filename' }) | ||
declare files?: string[] | ||
|
||
@flags.array({ description: 'Filter tests by tags' }) | ||
declare tags?: string[] | ||
|
||
@flags.array({ description: 'Run tests that does not have mentioned tags' }) | ||
declare ignoreTags?: string[] | ||
|
||
@flags.array({ description: 'Filter tests by parent group title' }) | ||
declare groups?: string[] | ||
|
||
@flags.array({ description: 'Filter tests by test title' }) | ||
declare tests?: string[] | ||
|
||
@flags.boolean({ description: 'Watch filesystem and re-run tests on file change' }) | ||
declare watch?: boolean | ||
|
||
@flags.boolean({ description: 'Use polling to detect filesystem changes' }) | ||
declare poll?: boolean | ||
|
||
@flags.boolean({ | ||
description: 'Clear the terminal for new logs after file change', | ||
showNegatedVariantInHelp: true, | ||
default: true, | ||
}) | ||
declare clear?: boolean | ||
|
||
@flags.boolean({ | ||
description: 'Start assets bundler dev server.', | ||
showNegatedVariantInHelp: true, | ||
default: true, | ||
}) | ||
declare assets?: boolean | ||
|
||
@flags.array({ | ||
description: 'Define CLI arguments to pass to the assets bundler', | ||
}) | ||
declare assetsArgs?: string[] | ||
|
||
/** | ||
* Log a development dependency is missing | ||
*/ | ||
#logMissingDevelopmentDependency(dependency: string) { | ||
this.logger.error( | ||
[ | ||
`Cannot find package "${dependency}"`, | ||
'', | ||
`The "${dependency}" package is a development dependency and therefore you should run tests with development dependencies installed.`, | ||
'', | ||
'If you are run tests inside a CI, make sure the NODE_ENV is set to "development"', | ||
].join('\n') | ||
) | ||
} | ||
|
||
/** | ||
* Runs tests | ||
*/ | ||
async run() { | ||
console.log(this.app.rcFile.tests) | ||
const assembler = await importAssembler(this.app) | ||
if (!assembler) { | ||
this.#logMissingDevelopmentDependency('@adonisjs/assembler') | ||
this.exitCode = 1 | ||
return | ||
} | ||
|
||
const assetsBundler = await detectAssetsBundler(this.app) | ||
|
||
const testRunner = new assembler.TestRunner(this.app.appRoot, { | ||
clearScreen: this.clear === false ? false : true, | ||
nodeArgs: this.parsed.nodeArgs, | ||
scriptArgs: this.parsed.unknownFlags | ||
.map((flag) => { | ||
const value = this.parsed.flags[flag] | ||
|
||
/** | ||
* Not mentioning value when value is "true" | ||
*/ | ||
if (value === true) { | ||
return [`--${flag}`] as string[] | ||
} | ||
|
||
/** | ||
* Repeating flag multiple times when value is an array | ||
*/ | ||
if (Array.isArray(value)) { | ||
return value.map((v) => [`--${flag}`, v]) as string[][] | ||
} | ||
|
||
return [`--${flag}`, value] as string[] | ||
}) | ||
.flat(2), | ||
assets: assetsBundler | ||
? { | ||
serve: this.assets === false ? false : true, | ||
driver: assetsBundler.name, | ||
cmd: assetsBundler.devServerCommand, | ||
args: this.assetsArgs || [], | ||
} | ||
: { | ||
serve: false, | ||
}, | ||
filters: { | ||
suites: this.suites, | ||
files: this.files, | ||
groups: this.groups, | ||
tags: this.tags, | ||
ignoreTags: this.ignoreTags, | ||
tests: this.tests, | ||
}, | ||
suites: this.app.rcFile.tests.suites.map((suite) => { | ||
return { | ||
name: suite.name, | ||
files: Array.isArray(suite.files) ? suite.files : [suite.files], | ||
} | ||
}), | ||
metaFiles: this.app.rcFile.metaFiles, | ||
}) | ||
|
||
/** | ||
* Share command logger with assembler, so that CLI flags like --no-ansi has | ||
* similar impact for assembler logs as well. | ||
*/ | ||
testRunner.setLogger(this.logger) | ||
|
||
/** | ||
* Exit command when the test runner is closed | ||
*/ | ||
testRunner.onClose((exitCode) => { | ||
this.exitCode = exitCode | ||
}) | ||
|
||
/** | ||
* Exit command when the dev server crashes | ||
*/ | ||
testRunner.onError(() => { | ||
this.exitCode = 1 | ||
}) | ||
|
||
/** | ||
* Start the test runner in watch mode | ||
*/ | ||
if (this.watch) { | ||
const ts = await importTypeScript(this.app) | ||
if (!ts) { | ||
this.#logMissingDevelopmentDependency('typescript') | ||
this.exitCode = 1 | ||
return | ||
} | ||
|
||
await testRunner.runAndWatch(ts, { poll: this.poll || false }) | ||
} else { | ||
await testRunner.run() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.