replace jest with ava
This commit is contained in:
parent
27cc8b23fe
commit
0347b72305
11775 changed files with 84546 additions and 1440575 deletions
449
node_modules/ava/lib/cli.js
generated
vendored
Normal file
449
node_modules/ava/lib/cli.js
generated
vendored
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
'use strict';
|
||||
const path = require('path');
|
||||
const del = require('del');
|
||||
const updateNotifier = require('update-notifier');
|
||||
const figures = require('figures');
|
||||
const arrify = require('arrify');
|
||||
const yargs = require('yargs');
|
||||
const readPkg = require('read-pkg');
|
||||
const isCi = require('./is-ci');
|
||||
const loadConfig = require('./load-config');
|
||||
|
||||
function exit(message) {
|
||||
console.error(`\n ${require('./chalk').get().red(figures.cross)} ${message}`);
|
||||
process.exit(1); // eslint-disable-line unicorn/no-process-exit
|
||||
}
|
||||
|
||||
const coerceLastValue = value => {
|
||||
return Array.isArray(value) ? value.pop() : value;
|
||||
};
|
||||
|
||||
const FLAGS = {
|
||||
concurrency: {
|
||||
alias: 'c',
|
||||
coerce: coerceLastValue,
|
||||
description: 'Max number of test files running at the same time (default: CPU cores)',
|
||||
type: 'number'
|
||||
},
|
||||
'fail-fast': {
|
||||
coerce: coerceLastValue,
|
||||
description: 'Stop after first test failure',
|
||||
type: 'boolean'
|
||||
},
|
||||
match: {
|
||||
alias: 'm',
|
||||
description: 'Only run tests with matching title (can be repeated)',
|
||||
type: 'string'
|
||||
},
|
||||
'node-arguments': {
|
||||
coerce: coerceLastValue,
|
||||
description: 'Additional Node.js arguments for launching worker processes (specify as a single string)',
|
||||
type: 'string'
|
||||
},
|
||||
serial: {
|
||||
alias: 's',
|
||||
coerce: coerceLastValue,
|
||||
description: 'Run tests serially',
|
||||
type: 'boolean'
|
||||
},
|
||||
tap: {
|
||||
alias: 't',
|
||||
coerce: coerceLastValue,
|
||||
description: 'Generate TAP output',
|
||||
type: 'boolean'
|
||||
},
|
||||
timeout: {
|
||||
alias: 'T',
|
||||
coerce: coerceLastValue,
|
||||
description: 'Set global timeout (milliseconds or human-readable, e.g. 10s, 2m)',
|
||||
type: 'string'
|
||||
},
|
||||
'update-snapshots': {
|
||||
alias: 'u',
|
||||
coerce: coerceLastValue,
|
||||
description: 'Update snapshots',
|
||||
type: 'boolean'
|
||||
},
|
||||
verbose: {
|
||||
alias: 'v',
|
||||
coerce: coerceLastValue,
|
||||
description: 'Enable verbose output',
|
||||
type: 'boolean'
|
||||
},
|
||||
watch: {
|
||||
alias: 'w',
|
||||
coerce: coerceLastValue,
|
||||
description: 'Re-run tests when files change',
|
||||
type: 'boolean'
|
||||
}
|
||||
};
|
||||
|
||||
exports.run = async () => { // eslint-disable-line complexity
|
||||
let conf = {};
|
||||
let confError = null;
|
||||
try {
|
||||
const {argv: {config: configFile}} = yargs.help(false);
|
||||
conf = loadConfig({configFile});
|
||||
} catch (error) {
|
||||
confError = error;
|
||||
}
|
||||
|
||||
let debug = null;
|
||||
let resetCache = false;
|
||||
const {argv} = yargs
|
||||
.parserConfiguration({
|
||||
'boolean-negation': true,
|
||||
'camel-case-expansion': false,
|
||||
'combine-arrays': false,
|
||||
'dot-notation': false,
|
||||
'duplicate-arguments-array': true,
|
||||
'flatten-duplicate-arrays': true,
|
||||
'negation-prefix': 'no-',
|
||||
'parse-numbers': true,
|
||||
'populate--': true,
|
||||
'set-placeholder-key': false,
|
||||
'short-option-groups': true,
|
||||
'strip-aliased': true,
|
||||
'unknown-options-as-args': false
|
||||
})
|
||||
.usage('$0 [<pattern>...]')
|
||||
.usage('$0 debug [<pattern>...]')
|
||||
.usage('$0 reset-cache')
|
||||
.options({
|
||||
color: {
|
||||
description: 'Force color output',
|
||||
type: 'boolean'
|
||||
},
|
||||
config: {
|
||||
description: 'Specific JavaScript file for AVA to read its config from, instead of using package.json or ava.config.* files'
|
||||
}
|
||||
})
|
||||
.command('* [<pattern>...]', 'Run tests', yargs => yargs.options(FLAGS).positional('pattern', {
|
||||
array: true,
|
||||
describe: 'Glob patterns to select what test files to run. Leave empty if you want AVA to run all test files instead. Add a colon and specify line numbers of specific tests to run',
|
||||
type: 'string'
|
||||
}))
|
||||
.command(
|
||||
'debug [<pattern>...]',
|
||||
'Activate Node.js inspector and run a single test file',
|
||||
yargs => yargs.options(FLAGS).options({
|
||||
break: {
|
||||
description: 'Break before the test file is loaded',
|
||||
type: 'boolean'
|
||||
},
|
||||
host: {
|
||||
default: '127.0.0.1',
|
||||
description: 'Address or hostname through which you can connect to the inspector',
|
||||
type: 'string'
|
||||
},
|
||||
port: {
|
||||
default: 9229,
|
||||
description: 'Port on which you can connect to the inspector',
|
||||
type: 'number'
|
||||
}
|
||||
}).positional('pattern', {
|
||||
demand: true,
|
||||
describe: 'Glob patterns to select a single test file to debug. Add a colon and specify line numbers of specific tests to run',
|
||||
type: 'string'
|
||||
}),
|
||||
argv => {
|
||||
debug = {
|
||||
break: argv.break === true,
|
||||
files: argv.pattern,
|
||||
host: argv.host,
|
||||
port: argv.port
|
||||
};
|
||||
})
|
||||
.command(
|
||||
'reset-cache',
|
||||
'Reset AVA’s compilation cache and exit',
|
||||
yargs => yargs,
|
||||
() => {
|
||||
resetCache = true;
|
||||
})
|
||||
.example('$0')
|
||||
.example('$0 test.js')
|
||||
.example('$0 test.js:4,7-9')
|
||||
.help();
|
||||
|
||||
const combined = {...conf};
|
||||
for (const flag of Object.keys(FLAGS)) {
|
||||
if (Reflect.has(argv, flag)) {
|
||||
if (flag === 'fail-fast') {
|
||||
combined.failFast = argv[flag];
|
||||
} else if (flag === 'update-snapshots') {
|
||||
combined.updateSnapshots = argv[flag];
|
||||
} else if (flag !== 'node-arguments') {
|
||||
combined[flag] = argv[flag];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const chalkOptions = {level: combined.color === false ? 0 : require('chalk').level};
|
||||
const chalk = require('./chalk').set(chalkOptions);
|
||||
|
||||
if (confError) {
|
||||
if (confError.parent) {
|
||||
exit(`${confError.message}\n\n${chalk.gray((confError.parent && confError.parent.stack) || confError.parent)}`);
|
||||
} else {
|
||||
exit(confError.message);
|
||||
}
|
||||
}
|
||||
|
||||
updateNotifier({pkg: require('../package.json')}).notify();
|
||||
|
||||
const {nonSemVerExperiments: experiments, projectDir} = conf;
|
||||
if (resetCache) {
|
||||
const cacheDir = path.join(projectDir, 'node_modules', '.cache', 'ava');
|
||||
try {
|
||||
await del('*', {
|
||||
cwd: cacheDir,
|
||||
nodir: true
|
||||
});
|
||||
console.error(`\n${chalk.green(figures.tick)} Removed AVA cache files in ${cacheDir}`);
|
||||
process.exit(0); // eslint-disable-line unicorn/no-process-exit
|
||||
} catch (error) {
|
||||
exit(`Error removing AVA cache files in ${cacheDir}\n\n${chalk.gray((error && error.stack) || error)}`);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv.watch) {
|
||||
if (argv.tap && !conf.tap) {
|
||||
exit('The TAP reporter is not available when using watch mode.');
|
||||
}
|
||||
|
||||
if (isCi) {
|
||||
exit('Watch mode is not available in CI, as it prevents AVA from terminating.');
|
||||
}
|
||||
|
||||
if (debug !== null) {
|
||||
exit('Watch mode is not available when debugging.');
|
||||
}
|
||||
}
|
||||
|
||||
if (debug !== null) {
|
||||
if (argv.tap && !conf.tap) {
|
||||
exit('The TAP reporter is not available when debugging.');
|
||||
}
|
||||
|
||||
if (isCi) {
|
||||
exit('Debugging is not available in CI.');
|
||||
}
|
||||
|
||||
if (combined.timeout) {
|
||||
console.log(chalk.magenta(` ${figures.warning} The timeout option has been disabled to help with debugging.`));
|
||||
}
|
||||
}
|
||||
|
||||
if (Reflect.has(combined, 'concurrency') && (!Number.isInteger(combined.concurrency) || combined.concurrency < 0)) {
|
||||
exit('The --concurrency or -c flag must be provided with a nonnegative integer.');
|
||||
}
|
||||
|
||||
if (!combined.tap && Object.keys(experiments).length > 0) {
|
||||
console.log(chalk.magenta(` ${figures.warning} Experiments are enabled. These are unsupported and may change or be removed at any time.`));
|
||||
}
|
||||
|
||||
if (Reflect.has(conf, 'compileEnhancements')) {
|
||||
exit('Enhancement compilation must be configured in AVA’s Babel options.');
|
||||
}
|
||||
|
||||
if (Reflect.has(conf, 'helpers')) {
|
||||
exit('AVA no longer compiles helpers. Add exclusion patterns to the ’files’ configuration and specify ’compileAsTests’ in the Babel options instead.');
|
||||
}
|
||||
|
||||
if (Reflect.has(conf, 'sources')) {
|
||||
exit('’sources’ has been removed. Use ’ignoredByWatcher’ to provide glob patterns of files that the watcher should ignore.');
|
||||
}
|
||||
|
||||
const ciParallelVars = require('ci-parallel-vars');
|
||||
const Api = require('./api');
|
||||
const VerboseReporter = require('./reporters/verbose');
|
||||
const MiniReporter = require('./reporters/mini');
|
||||
const TapReporter = require('./reporters/tap');
|
||||
const Watcher = require('./watcher');
|
||||
const normalizeExtensions = require('./extensions');
|
||||
const {normalizeGlobs, normalizePattern} = require('./globs');
|
||||
const normalizeNodeArguments = require('./node-arguments');
|
||||
const validateEnvironmentVariables = require('./environment-variables');
|
||||
const {splitPatternAndLineNumbers} = require('./line-numbers');
|
||||
const providerManager = require('./provider-manager');
|
||||
|
||||
let pkg;
|
||||
try {
|
||||
pkg = readPkg.sync({cwd: projectDir});
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const {type: defaultModuleType = 'commonjs'} = pkg || {};
|
||||
|
||||
const moduleTypes = {
|
||||
cjs: 'commonjs',
|
||||
mjs: 'module',
|
||||
js: defaultModuleType
|
||||
};
|
||||
|
||||
const providers = [];
|
||||
if (Reflect.has(conf, 'babel')) {
|
||||
try {
|
||||
const {level, main} = providerManager.babel(projectDir);
|
||||
providers.push({
|
||||
level,
|
||||
main: main({config: conf.babel}),
|
||||
type: 'babel'
|
||||
});
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (Reflect.has(conf, 'typescript')) {
|
||||
try {
|
||||
const {level, main} = providerManager.typescript(projectDir);
|
||||
providers.push({
|
||||
level,
|
||||
main: main({config: conf.typescript}),
|
||||
type: 'typescript'
|
||||
});
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
let environmentVariables;
|
||||
try {
|
||||
environmentVariables = validateEnvironmentVariables(conf.environmentVariables);
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
|
||||
let extensions;
|
||||
try {
|
||||
extensions = normalizeExtensions(conf.extensions, providers);
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
|
||||
let globs;
|
||||
try {
|
||||
globs = normalizeGlobs({files: conf.files, ignoredByWatcher: conf.ignoredByWatcher, extensions, providers});
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
|
||||
let nodeArguments;
|
||||
try {
|
||||
nodeArguments = normalizeNodeArguments(conf.nodeArguments, argv['node-arguments']);
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
|
||||
let parallelRuns = null;
|
||||
if (isCi && ciParallelVars) {
|
||||
const {index: currentIndex, total: totalRuns} = ciParallelVars;
|
||||
parallelRuns = {currentIndex, totalRuns};
|
||||
}
|
||||
|
||||
const match = combined.match === '' ? [] : arrify(combined.match);
|
||||
|
||||
const input = debug ? debug.files : (argv.pattern || []);
|
||||
const filter = input
|
||||
.map(pattern => splitPatternAndLineNumbers(pattern))
|
||||
.map(({pattern, ...rest}) => ({
|
||||
pattern: normalizePattern(path.relative(projectDir, path.resolve(process.cwd(), pattern))),
|
||||
...rest
|
||||
}));
|
||||
|
||||
const api = new Api({
|
||||
cacheEnabled: combined.cache !== false,
|
||||
chalkOptions,
|
||||
concurrency: combined.concurrency || 0,
|
||||
debug,
|
||||
environmentVariables,
|
||||
experiments,
|
||||
extensions,
|
||||
failFast: combined.failFast,
|
||||
failWithoutAssertions: combined.failWithoutAssertions !== false,
|
||||
globs,
|
||||
match,
|
||||
moduleTypes,
|
||||
nodeArguments,
|
||||
parallelRuns,
|
||||
projectDir,
|
||||
providers,
|
||||
ranFromCli: true,
|
||||
require: arrify(combined.require),
|
||||
serial: combined.serial,
|
||||
snapshotDir: combined.snapshotDir ? path.resolve(projectDir, combined.snapshotDir) : null,
|
||||
timeout: combined.timeout || '10s',
|
||||
updateSnapshots: combined.updateSnapshots,
|
||||
workerArgv: argv['--']
|
||||
});
|
||||
|
||||
let reporter;
|
||||
if (combined.tap && !combined.watch && debug === null) {
|
||||
reporter = new TapReporter({
|
||||
projectDir,
|
||||
reportStream: process.stdout,
|
||||
stdStream: process.stderr
|
||||
});
|
||||
} else if (debug !== null || combined.verbose || isCi || !process.stdout.isTTY) {
|
||||
reporter = new VerboseReporter({
|
||||
projectDir,
|
||||
reportStream: process.stdout,
|
||||
stdStream: process.stderr,
|
||||
watching: combined.watch
|
||||
});
|
||||
} else {
|
||||
reporter = new MiniReporter({
|
||||
projectDir,
|
||||
reportStream: process.stdout,
|
||||
stdStream: process.stderr,
|
||||
watching: combined.watch
|
||||
});
|
||||
}
|
||||
|
||||
api.on('run', plan => {
|
||||
reporter.startRun(plan);
|
||||
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'interrupt') {
|
||||
reporter.endRun();
|
||||
process.exit(1); // eslint-disable-line unicorn/no-process-exit
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (combined.watch) {
|
||||
const watcher = new Watcher({
|
||||
api,
|
||||
filter,
|
||||
globs,
|
||||
projectDir,
|
||||
providers,
|
||||
reporter
|
||||
});
|
||||
watcher.observeStdin(process.stdin);
|
||||
} else {
|
||||
let debugWithoutSpecificFile = false;
|
||||
api.on('run', plan => {
|
||||
if (plan.debug && plan.files.length !== 1) {
|
||||
debugWithoutSpecificFile = true;
|
||||
}
|
||||
});
|
||||
|
||||
const runStatus = await api.run({filter});
|
||||
|
||||
if (debugWithoutSpecificFile) {
|
||||
exit('Provide the path to the test file you wish to debug');
|
||||
return;
|
||||
}
|
||||
|
||||
process.exitCode = runStatus.suggestExitCode({matching: match.length > 0});
|
||||
reporter.endRun();
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue