aboutsummaryrefslogtreecommitdiff
path: root/node_modules/ava
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/ava')
-rw-r--r--node_modules/ava/api.js99
-rw-r--r--node_modules/ava/index.js.flow4
-rw-r--r--node_modules/ava/lib/assert.js32
-rw-r--r--node_modules/ava/lib/ava-files.js5
-rw-r--r--node_modules/ava/lib/babel-config.js8
-rw-r--r--node_modules/ava/lib/beautify-stack.js51
-rw-r--r--node_modules/ava/lib/caching-precompiler.js5
-rw-r--r--node_modules/ava/lib/cli.js14
-rw-r--r--node_modules/ava/lib/colors.js1
-rw-r--r--node_modules/ava/lib/enhance-assert.js22
-rw-r--r--node_modules/ava/lib/extract-stack.js10
-rw-r--r--node_modules/ava/lib/fork.js4
-rw-r--r--node_modules/ava/lib/logger.js11
-rw-r--r--node_modules/ava/lib/main.js3
-rw-r--r--node_modules/ava/lib/reporters/improper-usage-messages.js4
-rw-r--r--node_modules/ava/lib/reporters/mini.js53
-rw-r--r--node_modules/ava/lib/reporters/tap.js47
-rw-r--r--node_modules/ava/lib/reporters/verbose.js76
-rw-r--r--node_modules/ava/lib/run-status.js9
-rw-r--r--node_modules/ava/lib/runner.js7
-rw-r--r--node_modules/ava/lib/serialize-error.js9
-rw-r--r--node_modules/ava/lib/snapshot-manager.js30
-rw-r--r--node_modules/ava/lib/test-collection.js32
-rw-r--r--node_modules/ava/lib/test-worker.js13
-rw-r--r--node_modules/ava/lib/test.js10
-rw-r--r--node_modules/ava/lib/watcher.js20
-rw-r--r--node_modules/ava/node_modules/chalk/index.js18
-rw-r--r--node_modules/ava/node_modules/chalk/package.json15
-rw-r--r--node_modules/ava/node_modules/chalk/readme.md5
-rw-r--r--node_modules/ava/node_modules/chalk/templates.js32
-rw-r--r--node_modules/ava/package.json80
-rw-r--r--node_modules/ava/readme.md63
-rw-r--r--node_modules/ava/types/generated.d.ts8
33 files changed, 501 insertions, 299 deletions
diff --git a/node_modules/ava/api.js b/node_modules/ava/api.js
index 99213a757..9c6e775d6 100644
--- a/node_modules/ava/api.js
+++ b/node_modules/ava/api.js
@@ -2,9 +2,11 @@
const EventEmitter = require('events');
const path = require('path');
const fs = require('fs');
+const os = require('os');
const commonPathPrefix = require('common-path-prefix');
const uniqueTempDir = require('unique-temp-dir');
const findCacheDir = require('find-cache-dir');
+const isCi = require('is-ci');
const resolveCwd = require('resolve-cwd');
const debounce = require('lodash.debounce');
const autoBind = require('auto-bind');
@@ -53,6 +55,7 @@ class Api extends EventEmitter {
this.options = Object.assign({match: []}, options);
this.options.require = resolveModules(this.options.require);
}
+
_runFile(file, runStatus, execArgv) {
const hash = this.precompiler.precompileFile(file);
const precompiled = Object.assign({}, this._precompiledHelpers);
@@ -69,17 +72,20 @@ class Api extends EventEmitter {
return emitter;
}
+
run(files, options) {
return new AvaFiles({cwd: this.options.resolveTestsFrom, files})
.findTestFiles()
.then(files => this._run(files, options));
}
+
_onTimeout(runStatus) {
const timeout = ms(this.options.timeout);
const err = new AvaError(`Exited because no new tests completed within the last ${timeout}ms of inactivity`);
this._handleError(runStatus, err);
runStatus.emit('timeout');
}
+
_setupTimeout(runStatus) {
const timeout = ms(this.options.timeout);
@@ -90,9 +96,11 @@ class Api extends EventEmitter {
runStatus._restartTimer();
runStatus.on('test', runStatus._restartTimer);
}
+
_cancelTimeout(runStatus) {
runStatus._restartTimer.cancel();
}
+
_setupPrecompiler(files) {
const isCacheEnabled = this.options.cacheEnabled !== false;
let cacheDir = uniqueTempDir();
@@ -119,6 +127,7 @@ class Api extends EventEmitter {
});
});
}
+
_precompileHelpers() {
this._precompiledHelpers = {};
@@ -134,6 +143,7 @@ class Api extends EventEmitter {
this._precompiledHelpers[file] = hash;
});
}
+
_run(files, options) {
options = options || {};
@@ -160,18 +170,20 @@ class Api extends EventEmitter {
this._setupTimeout(runStatus);
}
- let overwatch;
+ let concurrency = Math.min(os.cpus().length, isCi ? 2 : Infinity);
+
if (this.options.concurrency > 0) {
- const concurrency = this.options.serial ? 1 : this.options.concurrency;
- overwatch = this._runWithPool(files, runStatus, concurrency);
- } else {
- // _runWithoutPool exists to preserve legacy behavior, specifically around `.only`
- overwatch = this._runWithoutPool(files, runStatus);
+ concurrency = this.options.concurrency;
+ }
+
+ if (this.options.serial) {
+ concurrency = 1;
}
- return overwatch;
+ return this._runWithPool(files, runStatus, concurrency);
});
}
+
_computeForkExecArgs(files) {
const execArgv = this.options.testOnlyExecArgv || process.execArgv;
let debugArgIndex = -1;
@@ -217,85 +229,14 @@ class Api extends EventEmitter {
return forkExecArgv;
});
}
+
_handleError(runStatus, err) {
runStatus.handleExceptions({
exception: err,
file: err.file ? path.relative(process.cwd(), err.file) : undefined
});
}
- _runWithoutPool(files, runStatus) {
- const tests = [];
- let execArgvList;
-
- // TODO: This should be cleared at the end of the run
- runStatus.on('timeout', () => {
- tests.forEach(fork => {
- fork.exit();
- });
- });
- return this._computeForkExecArgs(files)
- .then(argvList => {
- execArgvList = argvList;
- })
- .return(files)
- .each((file, index) => {
- return new Promise(resolve => {
- const forkArgs = execArgvList[index];
- const test = this._runFile(file, runStatus, forkArgs);
- tests.push(test);
- test.on('stats', resolve);
- test.catch(resolve);
- }).catch(err => {
- err.results = [];
- err.file = file;
- return Promise.reject(err);
- });
- })
- .then(() => {
- if (this.options.match.length > 0 && !runStatus.hasExclusive) {
- const err = new AvaError('Couldn\'t find any matching tests');
- err.file = undefined;
- err.results = [];
- return Promise.reject(err);
- }
-
- const method = this.options.serial ? 'mapSeries' : 'map';
- const options = {
- runOnlyExclusive: runStatus.hasExclusive
- };
-
- return Promise[method](files, (file, index) => {
- return tests[index].run(options).catch(err => {
- err.file = file;
- this._handleError(runStatus, err);
- return getBlankResults();
- });
- });
- })
- .catch(err => {
- this._handleError(runStatus, err);
- return err.results;
- })
- .tap(results => {
- // If no tests ran, make sure to tear down the child processes
- if (results.length === 0) {
- tests.forEach(test => {
- test.send('teardown');
- });
- }
- })
- .then(results => {
- // Cancel debounced _onTimeout() from firing
- if (this.options.timeout) {
- this._cancelTimeout(runStatus);
- }
-
- runStatus.processResults(results);
-
- return runStatus;
- });
- }
_runWithPool(files, runStatus, concurrency) {
const tests = [];
let execArgvList;
diff --git a/node_modules/ava/index.js.flow b/node_modules/ava/index.js.flow
index b86e22c65..e0bda9aef 100644
--- a/node_modules/ava/index.js.flow
+++ b/node_modules/ava/index.js.flow
@@ -69,7 +69,7 @@ type AssertContext = {
// Assert that contents matches regex.
regex(contents: string, regex: RegExp, message?: string): void;
// Assert that contents matches a snapshot.
- snapshot(contents: any, message?: string): void;
+ snapshot: ((contents: any, message?: string) => void) & ((contents: any, options: {id: string}, message?: string) => void);
// Assert that contents does not match regex.
notRegex(contents: string, regex: RegExp, message?: string): void;
// Assert that error is falsy.
@@ -81,8 +81,10 @@ type AssertContext = {
*/
type TestContext = AssertContext & {
+ title: string;
plan(count: number): void;
skip: AssertContext;
+ log(message: string): void;
};
type ContextualTestContext = TestContext & { context: any; };
type ContextualCallbackTestContext = TestContext & { context: any; end(): void; };
diff --git a/node_modules/ava/lib/assert.js b/node_modules/ava/lib/assert.js
index a0e9fe82c..18009b97d 100644
--- a/node_modules/ava/lib/assert.js
+++ b/node_modules/ava/lib/assert.js
@@ -64,6 +64,7 @@ function wrapAssertions(callbacks) {
const pass = callbacks.pass;
const pending = callbacks.pending;
const fail = callbacks.fail;
+ const log = callbacks.log;
const noop = () => {};
const makeRethrow = reason => () => {
@@ -86,14 +87,25 @@ function wrapAssertions(callbacks) {
if (Object.is(actual, expected)) {
pass(this);
} else {
- const actualDescriptor = concordance.describe(actual, concordanceOptions);
- const expectedDescriptor = concordance.describe(expected, concordanceOptions);
- fail(this, new AssertionError({
- assertion: 'is',
- message,
- raw: {actual, expected},
- values: [formatDescriptorDiff(actualDescriptor, expectedDescriptor)]
- }));
+ const result = concordance.compare(actual, expected, concordanceOptions);
+ const actualDescriptor = result.actual || concordance.describe(actual, concordanceOptions);
+ const expectedDescriptor = result.expected || concordance.describe(expected, concordanceOptions);
+
+ if (result.pass) {
+ fail(this, new AssertionError({
+ assertion: 'is',
+ message,
+ raw: {actual, expected},
+ values: [formatDescriptorWithLabel('Values are deeply equal to each other, but they are not the same:', actualDescriptor)]
+ }));
+ } else {
+ fail(this, new AssertionError({
+ assertion: 'is',
+ message,
+ raw: {actual, expected},
+ values: [formatDescriptorDiff(actualDescriptor, expectedDescriptor)]
+ }));
+ }
}
},
@@ -110,6 +122,10 @@ function wrapAssertions(callbacks) {
}
},
+ log(text) {
+ log(this, text);
+ },
+
deepEqual(actual, expected, message) {
const result = concordance.compare(actual, expected, concordanceOptions);
if (result.pass) {
diff --git a/node_modules/ava/lib/ava-files.js b/node_modules/ava/lib/ava-files.js
index cfdc9f202..b6520da37 100644
--- a/node_modules/ava/lib/ava-files.js
+++ b/node_modules/ava/lib/ava-files.js
@@ -125,6 +125,7 @@ class AvaFiles {
autoBind(this);
}
+
findTestFiles() {
return handlePaths(this.files, this.excludePatterns, {
cwd: this.cwd,
@@ -134,6 +135,7 @@ class AvaFiles {
symlinks: Object.create(null)
});
}
+
findTestHelpers() {
return handlePaths(defaultHelperPatterns(), ['!**/node_modules/**'], {
cwd: this.cwd,
@@ -144,6 +146,7 @@ class AvaFiles {
symlinks: Object.create(null)
});
}
+
isSource(filePath) {
let mixedPatterns = [];
const defaultIgnorePatterns = getDefaultIgnorePatterns();
@@ -195,6 +198,7 @@ class AvaFiles {
return false;
}
+
isTest(filePath) {
const excludePatterns = this.excludePatterns;
const initialPatterns = this.files.concat(excludePatterns);
@@ -241,6 +245,7 @@ class AvaFiles {
// excludePatterns into account. This mimicks the behavior in api.js
return multimatch(matchable(filePath), recursivePatterns.concat(excludePatterns)).length === 1;
}
+
getChokidarPatterns() {
let paths = [];
let ignored = [];
diff --git a/node_modules/ava/lib/babel-config.js b/node_modules/ava/lib/babel-config.js
index 62e841f05..d58b700b8 100644
--- a/node_modules/ava/lib/babel-config.js
+++ b/node_modules/ava/lib/babel-config.js
@@ -6,6 +6,7 @@ const figures = require('figures');
const configManager = require('hullabaloo-config-manager');
const md5Hex = require('md5-hex');
const makeDir = require('make-dir');
+const semver = require('semver');
const colors = require('./colors');
function validate(conf) {
@@ -99,6 +100,7 @@ function build(projectDir, cacheDir, userOptions, powerAssert) {
const baseOptions = {
babelrc: false,
+ plugins: [],
presets: [
['@ava/transform-test-files', {powerAssert}]
]
@@ -107,6 +109,12 @@ function build(projectDir, cacheDir, userOptions, powerAssert) {
baseOptions.presets.unshift('@ava/stage-4');
}
+ // Include object rest spread support for node versions that support it
+ // natively.
+ if (userOptions === 'default' && semver.satisfies(process.versions.node, '>= 8.3.0')) {
+ baseOptions.plugins.push('babel-plugin-syntax-object-rest-spread');
+ }
+
const baseConfig = configManager.createConfig({
dir: AVA_DIR, // Presets are resolved relative to this directory
hash: md5Hex(JSON.stringify(baseOptions)),
diff --git a/node_modules/ava/lib/beautify-stack.js b/node_modules/ava/lib/beautify-stack.js
index 189ed0714..4ae8c04be 100644
--- a/node_modules/ava/lib/beautify-stack.js
+++ b/node_modules/ava/lib/beautify-stack.js
@@ -8,6 +8,7 @@ let ignoreStackLines = [];
const avaInternals = /\/ava\/(?:lib\/)?[\w-]+\.js:\d+:\d+\)?$/;
const avaDependencies = /\/node_modules\/(?:bluebird|empower-core|(?:ava\/node_modules\/)?(?:babel-runtime|core-js))\//;
+const stackFrameLine = /^.+( \(.+:\d+:\d+\)|:\d+:\d+)$/;
if (!debug.enabled) {
ignoreStackLines = StackUtils.nodeInternals();
@@ -17,21 +18,55 @@ if (!debug.enabled) {
const stackUtils = new StackUtils({internals: ignoreStackLines});
+function extractFrames(stack) {
+ return stack
+ .split('\n')
+ .map(line => line.trim())
+ .filter(line => stackFrameLine.test(line))
+ .join('\n');
+}
+
+/**
+ * Given a string value of the format generated for the `stack` property of a
+ * V8 error object, return a string that contains only stack frame information
+ * for frames that have relevance to the consumer.
+ *
+ * For example, given the following string value:
+ *
+ * ```
+ * Error
+ * at inner (/home/ava/ex.js:7:12)
+ * at /home/ava/ex.js:12:5
+ * at outer (/home/ava/ex.js:13:4)
+ * at Object.<anonymous> (/home/ava/ex.js:14:3)
+ * at Module._compile (module.js:570:32)
+ * at Object.Module._extensions..js (module.js:579:10)
+ * at Module.load (module.js:487:32)
+ * at tryModuleLoad (module.js:446:12)
+ * at Function.Module._load (module.js:438:3)
+ * at Module.runMain (module.js:604:10)
+ * ```
+ *
+ * ...this function returns the following string value:
+ *
+ * ```
+ * inner (/home/ava/ex.js:7:12)
+ * /home/ava/ex.js:12:5
+ * outer (/home/ava/ex.js:13:4)
+ * Object.<anonymous> (/home/ava/ex.js:14:3)
+ * ```
+ */
module.exports = stack => {
if (!stack) {
return '';
}
+ stack = extractFrames(stack);
// Workaround for https://github.com/tapjs/stack-utils/issues/14
// TODO: fix it in `stack-utils`
stack = cleanStack(stack);
- const title = stack.split('\n')[0];
- const lines = stackUtils
- .clean(stack)
- .split('\n')
- .map(x => ` ${x}`)
- .join('\n');
-
- return `${title}\n${lines}`;
+ return stackUtils.clean(stack)
+ // Remove the trailing newline inserted by the `stack-utils` module
+ .trim();
};
diff --git a/node_modules/ava/lib/caching-precompiler.js b/node_modules/ava/lib/caching-precompiler.js
index 937309bf0..f6e5e47c3 100644
--- a/node_modules/ava/lib/caching-precompiler.js
+++ b/node_modules/ava/lib/caching-precompiler.js
@@ -33,6 +33,7 @@ class CachingPrecompiler {
this.fileHashes = {};
this.transform = this._createTransform();
}
+
precompileFile(filePath) {
if (!this.fileHashes[filePath]) {
const source = stripBomBuf(fs.readFileSync(filePath));
@@ -41,11 +42,13 @@ class CachingPrecompiler {
return this.fileHashes[filePath];
}
+
// Conditionally called by caching-transform when precompiling is required
_init() {
this.babel = require('babel-core');
return this._transform;
}
+
_transform(code, filePath, hash) {
code = code.toString();
@@ -79,6 +82,7 @@ class CachingPrecompiler {
return `${result.code}\n${comment}`;
}
+
_createTransform() {
const salt = packageHash.sync([
require.resolve('../package.json'),
@@ -93,6 +97,7 @@ class CachingPrecompiler {
ext: '.js'
});
}
+
_generateHash(code, filePath, salt) {
const hash = md5Hex([code, filePath, salt]);
this.fileHashes[filePath] = hash;
diff --git a/node_modules/ava/lib/cli.js b/node_modules/ava/lib/cli.js
index 5649a8190..0c2c2f82f 100644
--- a/node_modules/ava/lib/cli.js
+++ b/node_modules/ava/lib/cli.js
@@ -43,7 +43,7 @@ exports.run = () => {
--match, -m Only run tests with matching title (Can be repeated)
--watch, -w Re-run tests when tests and source files change
--timeout, -T Set global timeout
- --concurrency, -c Maximum number of test files running at the same time (EXPERIMENTAL)
+ --concurrency, -c Max number of test files running at the same time (Default: CPU cores)
--update-snapshots, -u Update snapshots
Examples
@@ -75,7 +75,7 @@ exports.run = () => {
],
default: {
cache: conf.cache,
- color: 'color' in conf ? conf.color : require('supports-color') !== false,
+ color: 'color' in conf ? conf.color : require('supports-color').stdout !== false,
concurrency: conf.concurrency,
failFast: conf.failFast,
init: conf.init,
@@ -119,7 +119,12 @@ exports.run = () => {
}
if (cli.flags.concurrency === '') {
- throw new Error(colors.error(figures.cross) + ' The --concurrency and -c flags must be provided the maximum number of test files to run at once.');
+ throw new Error(colors.error(figures.cross) + ' The --concurrency and -c flags must be provided.');
+ }
+
+ if (cli.flags.concurrency &&
+ (!Number.isInteger(Number.parseFloat(cli.flags.concurrency)) || parseInt(cli.flags.concurrency, 10) < 0)) {
+ throw new Error(colors.error(figures.cross) + ' The --concurrency and -c flags must be a nonnegative integer.');
}
if (hasFlag('--require') || hasFlag('-r')) {
@@ -144,6 +149,7 @@ exports.run = () => {
timeout: conf.timeout,
concurrency: conf.concurrency ? parseInt(conf.concurrency, 10) : 0,
updateSnapshots: conf.updateSnapshots,
+ snapshotDir: conf.snapshotDir ? path.resolve(projectDir, conf.snapshotDir) : null,
color: conf.color
});
@@ -152,7 +158,7 @@ exports.run = () => {
if (conf.tap && !conf.watch) {
reporter = new TapReporter();
} else if (conf.verbose || isCi) {
- reporter = new VerboseReporter({color: conf.color});
+ reporter = new VerboseReporter({color: conf.color, watching: conf.watch});
} else {
reporter = new MiniReporter({color: conf.color, watching: conf.watch});
}
diff --git a/node_modules/ava/lib/colors.js b/node_modules/ava/lib/colors.js
index 74be14bb1..75fb4d8aa 100644
--- a/node_modules/ava/lib/colors.js
+++ b/node_modules/ava/lib/colors.js
@@ -2,6 +2,7 @@
const chalk = require('chalk');
module.exports = {
+ log: chalk.gray,
title: chalk.bold.white,
error: chalk.red,
skip: chalk.yellow,
diff --git a/node_modules/ava/lib/enhance-assert.js b/node_modules/ava/lib/enhance-assert.js
index 6e127b3d6..6991caf40 100644
--- a/node_modules/ava/lib/enhance-assert.js
+++ b/node_modules/ava/lib/enhance-assert.js
@@ -1,6 +1,7 @@
'use strict';
const concordance = require('concordance');
const dotProp = require('dot-prop');
+const generate = require('babel-generator').default;
const concordanceOptions = require('./concordance-options').default;
// When adding patterns, don't forget to add to
@@ -15,31 +16,16 @@ const PATTERNS = [
't.notRegex(contents, regex, [message])'
];
-const isRangeMatch = (a, b) => {
- return (a[0] === b[0] && a[1] === b[1]) ||
- (a[0] > b[0] && a[0] < b[1]) ||
- (a[1] > b[0] && a[1] < b[1]);
-};
-
-const computeStatement = (tokens, range) => {
- return tokens
- .filter(token => isRangeMatch(token.range, range))
- .map(token => token.value === undefined ? token.type.label : token.value)
- .join('');
-};
-
+const computeStatement = node => generate(node, {quotes: 'single'}).code;
const getNode = (ast, path) => dotProp.get(ast, path.replace(/\//g, '.'));
const formatter = context => {
const ast = JSON.parse(context.source.ast);
- const tokens = JSON.parse(context.source.tokens);
const args = context.args[0].events;
-
return args
.map(arg => {
- const range = getNode(ast, arg.espath).range;
- const statement = computeStatement(tokens, range);
-
+ const node = getNode(ast, arg.espath);
+ const statement = computeStatement(node);
const formatted = concordance.format(arg.value, concordanceOptions);
return [statement, formatted];
})
diff --git a/node_modules/ava/lib/extract-stack.js b/node_modules/ava/lib/extract-stack.js
deleted file mode 100644
index 64f63db1c..000000000
--- a/node_modules/ava/lib/extract-stack.js
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict';
-const stackLineRegex = /^.+ \(.+:[0-9]+:[0-9]+\)$/;
-
-module.exports = stack => {
- return stack
- .split('\n')
- .filter(line => stackLineRegex.test(line))
- .map(line => line.trim())
- .join('\n');
-};
diff --git a/node_modules/ava/lib/fork.js b/node_modules/ava/lib/fork.js
index bf918d391..0ca0f45a4 100644
--- a/node_modules/ava/lib/fork.js
+++ b/node_modules/ava/lib/fork.js
@@ -10,12 +10,10 @@ if (fs.realpathSync(__filename) !== __filename) {
console.warn('WARNING: `npm link ava` and the `--preserve-symlink` flag are incompatible. We have detected that AVA is linked via `npm link`, and that you are using either an early version of Node 6, or the `--preserve-symlink` flag. This breaks AVA. You should upgrade to Node 6.2.0+, avoid the `--preserve-symlink` flag, or avoid using `npm link ava`.');
}
-let env = process.env;
+const env = Object.assign({NODE_ENV: 'test'}, process.env);
// Ensure NODE_PATH paths are absolute
if (env.NODE_PATH) {
- env = Object.assign({}, env);
-
env.NODE_PATH = env.NODE_PATH
.split(path.delimiter)
.map(x => path.resolve(x))
diff --git a/node_modules/ava/lib/logger.js b/node_modules/ava/lib/logger.js
index 54bd23c94..e8edb120f 100644
--- a/node_modules/ava/lib/logger.js
+++ b/node_modules/ava/lib/logger.js
@@ -6,6 +6,7 @@ class Logger {
this.reporter = reporter;
autoBind(this);
}
+
start(runStatus) {
if (!this.reporter.start) {
return;
@@ -13,6 +14,7 @@ class Logger {
this.write(this.reporter.start(runStatus), runStatus);
}
+
reset(runStatus) {
if (!this.reporter.reset) {
return;
@@ -20,9 +22,11 @@ class Logger {
this.write(this.reporter.reset(runStatus), runStatus);
}
+
test(test, runStatus) {
this.write(this.reporter.test(test, runStatus), runStatus);
}
+
unhandledError(err, runStatus) {
if (!this.reporter.unhandledError) {
return;
@@ -30,6 +34,7 @@ class Logger {
this.write(this.reporter.unhandledError(err, runStatus), runStatus);
}
+
finish(runStatus) {
if (!this.reporter.finish) {
return;
@@ -37,6 +42,7 @@ class Logger {
this.write(this.reporter.finish(runStatus), runStatus);
}
+
section() {
if (!this.reporter.section) {
return;
@@ -44,6 +50,7 @@ class Logger {
this.write(this.reporter.section());
}
+
clear() {
if (!this.reporter.clear) {
return false;
@@ -52,6 +59,7 @@ class Logger {
this.write(this.reporter.clear());
return true;
}
+
write(str, runStatus) {
if (typeof str === 'undefined') {
return;
@@ -59,6 +67,7 @@ class Logger {
this.reporter.write(str, runStatus);
}
+
stdout(data, runStatus) {
if (!this.reporter.stdout) {
return;
@@ -66,6 +75,7 @@ class Logger {
this.reporter.stdout(data, runStatus);
}
+
stderr(data, runStatus) {
if (!this.reporter.stderr) {
return;
@@ -73,6 +83,7 @@ class Logger {
this.reporter.stderr(data, runStatus);
}
+
exit(code) {
process.exit(code); // eslint-disable-line unicorn/no-process-exit
}
diff --git a/node_modules/ava/lib/main.js b/node_modules/ava/lib/main.js
index 1b03cc854..4c5fdc373 100644
--- a/node_modules/ava/lib/main.js
+++ b/node_modules/ava/lib/main.js
@@ -13,7 +13,8 @@ const runner = new Runner({
match: opts.match,
projectDir: opts.projectDir,
serial: opts.serial,
- updateSnapshots: opts.updateSnapshots
+ updateSnapshots: opts.updateSnapshots,
+ snapshotDir: opts.snapshotDir
});
worker.setRunner(runner);
diff --git a/node_modules/ava/lib/reporters/improper-usage-messages.js b/node_modules/ava/lib/reporters/improper-usage-messages.js
index 298ef79a5..014a4bf0d 100644
--- a/node_modules/ava/lib/reporters/improper-usage-messages.js
+++ b/node_modules/ava/lib/reporters/improper-usage-messages.js
@@ -15,7 +15,9 @@ exports.forError = error => {
Visit the following URL for more details:
${chalk.blue.underline('https://github.com/avajs/ava#throwsfunctionpromise-error-message')}`;
- } else if (assertion === 'snapshot') {
+ }
+
+ if (assertion === 'snapshot') {
const name = error.improperUsage.name;
const snapPath = error.improperUsage.snapPath;
diff --git a/node_modules/ava/lib/reporters/mini.js b/node_modules/ava/lib/reporters/mini.js
index 8acfab8e7..a21d02a6b 100644
--- a/node_modules/ava/lib/reporters/mini.js
+++ b/node_modules/ava/lib/reporters/mini.js
@@ -5,12 +5,12 @@ const lastLineTracker = require('last-line-stream/tracker');
const plur = require('plur');
const spinners = require('cli-spinners');
const chalk = require('chalk');
+const figures = require('figures');
const cliTruncate = require('cli-truncate');
const cross = require('figures').cross;
const indentString = require('indent-string');
const ansiEscapes = require('ansi-escapes');
const trimOffNewlines = require('trim-off-newlines');
-const extractStack = require('../extract-stack');
const codeExcerpt = require('../code-excerpt');
const colors = require('../colors');
const formatSerializedError = require('./format-serialized-error');
@@ -33,6 +33,7 @@ class MiniReporter {
this.stream = process.stderr;
this.stringDecoder = new StringDecoder();
}
+
start() {
this.interval = setInterval(() => {
this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
@@ -41,6 +42,7 @@ class MiniReporter {
return this.prefix('');
}
+
reset() {
this.clearInterval();
this.passCount = 0;
@@ -56,13 +58,16 @@ class MiniReporter {
this.spinnerIndex = 0;
this.lastLineTracker = lastLineTracker();
}
+
spinnerChar() {
return this.spinnerFrames[this.spinnerIndex];
}
+
clearInterval() {
clearInterval(this.interval);
this.interval = null;
}
+
test(test) {
if (test.todo) {
this.todoCount++;
@@ -83,6 +88,7 @@ class MiniReporter {
return this.prefix(this._test(test));
}
+
prefix(str) {
str = str || this.currentTest;
this.currentTest = str;
@@ -91,6 +97,7 @@ class MiniReporter {
// TODO(jamestalmage): Figure out why it's needed and document it here
return ` \n ${this.spinnerChar()} ${str}`;
}
+
_test(test) {
const SPINNER_WIDTH = 3;
const PADDING = 1;
@@ -102,6 +109,7 @@ class MiniReporter {
return title + '\n' + this.reportCounts();
}
+
unhandledError(err) {
if (err.type === 'exception') {
this.exceptionCount++;
@@ -109,6 +117,7 @@ class MiniReporter {
this.rejectionCount++;
}
}
+
reportCounts(time) {
const lines = [
this.passCount > 0 ? '\n ' + colors.pass(this.passCount, 'passed') : '',
@@ -124,6 +133,7 @@ class MiniReporter {
return lines.join('');
}
+
finish(runStatus) {
this.clearInterval();
let time;
@@ -163,6 +173,21 @@ class MiniReporter {
}
status += ' ' + colors.title(test.title) + '\n';
+
+ if (test.logs) {
+ test.logs.forEach(log => {
+ const logLines = indentString(colors.log(log), 6);
+ const logLinesWithLeadingFigure = logLines.replace(
+ /^ {6}/,
+ ` ${colors.information(figures.info)} `
+ );
+
+ status += logLinesWithLeadingFigure + '\n';
+ });
+
+ status += '\n';
+ }
+
if (test.error.source) {
status += ' ' + colors.errorSource(test.error.source.file + ':' + test.error.source.line) + '\n';
@@ -191,9 +216,9 @@ class MiniReporter {
}
if (test.error.stack) {
- const extracted = extractStack(test.error.stack);
- if (extracted.includes('\n')) {
- status += '\n' + indentString(colors.errorStack(extracted), 2) + '\n';
+ const stack = test.error.stack;
+ if (stack.includes('\n')) {
+ status += '\n' + indentString(colors.errorStack(stack), 2) + '\n';
}
}
@@ -212,14 +237,14 @@ class MiniReporter {
status += ' ' + colors.error(cross + ' ' + err.message) + '\n\n';
} else {
const title = err.type === 'rejection' ? 'Unhandled Rejection' : 'Uncaught Exception';
- let description = err.stack ? err.stack.trimRight() : JSON.stringify(err);
- description = description.split('\n');
- const errorTitle = err.name ? description[0] : 'Threw non-error: ' + description[0];
- const errorStack = description.slice(1).join('\n');
-
status += ' ' + colors.title(title) + '\n';
- status += ' ' + colors.stack(errorTitle) + '\n';
- status += colors.errorStack(errorStack) + '\n\n';
+
+ if (err.name) {
+ status += ' ' + colors.stack(err.summary) + '\n';
+ status += colors.errorStack(err.stack) + '\n\n';
+ } else {
+ status += ' Threw non-error: ' + err.summary + '\n';
+ }
}
});
}
@@ -235,24 +260,30 @@ class MiniReporter {
return '\n' + trimOffNewlines(status) + '\n';
}
+
section() {
return '\n' + chalk.gray.dim('\u2500'.repeat(process.stdout.columns || 80));
}
+
clear() {
return '';
}
+
write(str) {
cliCursor.hide();
this.currentStatus = str;
this._update();
this.statusLineCount = this.currentStatus.split('\n').length;
}
+
stdout(data) {
this._update(data);
}
+
stderr(data) {
this._update(data);
}
+
_update(data) {
let str = '';
let ct = this.statusLineCount;
diff --git a/node_modules/ava/lib/reporters/tap.js b/node_modules/ava/lib/reporters/tap.js
index 37c2cfd95..5ef8a23e3 100644
--- a/node_modules/ava/lib/reporters/tap.js
+++ b/node_modules/ava/lib/reporters/tap.js
@@ -3,12 +3,6 @@ const format = require('util').format;
const indentString = require('indent-string');
const stripAnsi = require('strip-ansi');
const yaml = require('js-yaml');
-const extractStack = require('../extract-stack');
-
-// Parses stack trace and extracts original function name, file name and line
-function getSourceFromStack(stack) {
- return extractStack(stack).split('\n')[0];
-}
function dumpError(error, includeMessage) {
const obj = Object.assign({}, error.object);
@@ -35,7 +29,7 @@ function dumpError(error, includeMessage) {
}
if (error.stack) {
- obj.at = getSourceFromStack(error.stack);
+ obj.at = error.stack.split('\n')[0];
}
return ` ---\n${indentString(yaml.safeDump(obj).trim(), 4)}\n ...`;
@@ -45,11 +39,13 @@ class TapReporter {
constructor() {
this.i = 0;
}
+
start() {
return 'TAP version 13';
}
+
test(test) {
- let output;
+ const output = [];
let directive = '';
const passed = test.todo ? 'not ok' : 'ok';
@@ -62,21 +58,34 @@ class TapReporter {
const title = stripAnsi(test.title);
+ const appendLogs = () => {
+ if (test.logs) {
+ test.logs.forEach(log => {
+ const logLines = indentString(log, 4);
+ const logLinesWithLeadingFigure = logLines.replace(
+ /^ {4}/,
+ ' * '
+ );
+
+ output.push(logLinesWithLeadingFigure);
+ });
+ }
+ };
+
+ output.push(`# ${title}`);
+
if (test.error) {
- output = [
- '# ' + title,
- format('not ok %d - %s', ++this.i, title),
- dumpError(test.error, true)
- ];
+ output.push(format('not ok %d - %s', ++this.i, title));
+ appendLogs();
+ output.push(dumpError(test.error, true));
} else {
- output = [
- `# ${title}`,
- format('%s %d - %s %s', passed, ++this.i, title, directive).trim()
- ];
+ output.push(format('%s %d - %s %s', passed, ++this.i, title, directive).trim());
+ appendLogs();
}
return output.join('\n');
}
+
unhandledError(err) {
const output = [
`# ${err.message}`,
@@ -89,6 +98,7 @@ class TapReporter {
return output.join('\n');
}
+
finish(runStatus) {
const output = [
'',
@@ -105,12 +115,15 @@ class TapReporter {
return output.join('\n');
}
+
write(str) {
console.log(str);
}
+
stdout(data) {
process.stderr.write(data);
}
+
stderr(data) {
this.stdout(data);
}
diff --git a/node_modules/ava/lib/reporters/verbose.js b/node_modules/ava/lib/reporters/verbose.js
index cd47683e8..c58d8db3b 100644
--- a/node_modules/ava/lib/reporters/verbose.js
+++ b/node_modules/ava/lib/reporters/verbose.js
@@ -5,7 +5,6 @@ const figures = require('figures');
const chalk = require('chalk');
const plur = require('plur');
const trimOffNewlines = require('trim-off-newlines');
-const extractStack = require('../extract-stack');
const codeExcerpt = require('../code-excerpt');
const colors = require('../colors');
const formatSerializedError = require('./format-serialized-error');
@@ -20,34 +19,46 @@ class VerboseReporter {
colors[key].enabled = this.options.color;
}
}
+
start() {
return '';
}
+
test(test, runStatus) {
+ const lines = [];
if (test.error) {
- return ' ' + colors.error(figures.cross) + ' ' + test.title + ' ' + colors.error(test.error.message);
- }
-
- if (test.todo) {
- return ' ' + colors.todo('- ' + test.title);
+ lines.push(' ' + colors.error(figures.cross) + ' ' + test.title + ' ' + colors.error(test.error.message));
+ } else if (test.todo) {
+ lines.push(' ' + colors.todo('- ' + test.title));
} else if (test.skip) {
- return ' ' + colors.skip('- ' + test.title);
- }
+ lines.push(' ' + colors.skip('- ' + test.title));
+ } else if (test.failing) {
+ lines.push(' ' + colors.error(figures.tick) + ' ' + colors.error(test.title));
+ } else if (runStatus.fileCount === 1 && runStatus.testCount === 1 && test.title === '[anonymous]') {
+ // No output
+ } else {
+ // Display duration only over a threshold
+ const threshold = 100;
+ const duration = test.duration > threshold ? colors.duration(' (' + prettyMs(test.duration) + ')') : '';
- if (test.failing) {
- return ' ' + colors.error(figures.tick) + ' ' + colors.error(test.title);
+ lines.push(' ' + colors.pass(figures.tick) + ' ' + test.title + duration);
}
- if (runStatus.fileCount === 1 && runStatus.testCount === 1 && test.title === '[anonymous]') {
- return undefined;
- }
+ if (test.logs) {
+ test.logs.forEach(log => {
+ const logLines = indentString(colors.log(log), 6);
+ const logLinesWithLeadingFigure = logLines.replace(
+ /^ {6}/,
+ ` ${colors.information(figures.info)} `
+ );
- // Display duration only over a threshold
- const threshold = 100;
- const duration = test.duration > threshold ? colors.duration(' (' + prettyMs(test.duration) + ')') : '';
+ lines.push(logLinesWithLeadingFigure);
+ });
+ }
- return ' ' + colors.pass(figures.tick) + ' ' + test.title + duration;
+ return lines.length > 0 ? lines.join('\n') : undefined;
}
+
unhandledError(err) {
if (err.type === 'exception' && err.name === 'AvaError') {
return colors.error(' ' + figures.cross + ' ' + err.message);
@@ -61,6 +72,7 @@ class VerboseReporter {
let output = colors.error(types[err.type] + ':', err.file) + '\n';
if (err.stack) {
+ output += ' ' + colors.stack(err.title || err.summary) + '\n';
output += ' ' + colors.stack(err.stack) + '\n';
} else {
output += ' ' + colors.stack(JSON.stringify(err)) + '\n';
@@ -70,6 +82,7 @@ class VerboseReporter {
return output;
}
+
finish(runStatus) {
let output = '';
@@ -86,7 +99,9 @@ class VerboseReporter {
].filter(Boolean);
if (lines.length > 0) {
- lines[0] += ' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']');
+ if (this.options.watching) {
+ lines[0] += ' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']');
+ }
output += lines.join('\n') + '\n';
}
@@ -104,6 +119,21 @@ class VerboseReporter {
}
output += ' ' + colors.title(test.title) + '\n';
+
+ if (test.logs) {
+ test.logs.forEach(log => {
+ const logLines = indentString(colors.log(log), 6);
+ const logLinesWithLeadingFigure = logLines.replace(
+ /^ {6}/,
+ ` ${colors.information(figures.info)} `
+ );
+
+ output += logLinesWithLeadingFigure + '\n';
+ });
+
+ output += '\n';
+ }
+
if (test.error.source) {
output += ' ' + colors.errorSource(test.error.source.file + ':' + test.error.source.line) + '\n';
@@ -132,9 +162,9 @@ class VerboseReporter {
}
if (test.error.stack) {
- const extracted = extractStack(test.error.stack);
- if (extracted.includes('\n')) {
- output += '\n' + indentString(colors.errorStack(extracted), 2) + '\n';
+ const stack = test.error.stack;
+ if (stack.includes('\n')) {
+ output += '\n' + indentString(colors.errorStack(stack), 2) + '\n';
}
}
@@ -153,15 +183,19 @@ class VerboseReporter {
return '\n' + trimOffNewlines(output) + '\n';
}
+
section() {
return chalk.gray.dim('\u2500'.repeat(process.stdout.columns || 80));
}
+
write(str) {
console.error(str);
}
+
stdout(data) {
process.stderr.write(data);
}
+
stderr(data) {
process.stderr.write(data);
}
diff --git a/node_modules/ava/lib/run-status.js b/node_modules/ava/lib/run-status.js
index 8e095655a..461ab8f90 100644
--- a/node_modules/ava/lib/run-status.js
+++ b/node_modules/ava/lib/run-status.js
@@ -44,6 +44,7 @@ class RunStatus extends EventEmitter {
autoBind(this);
}
+
observeFork(emitter) {
emitter
.on('teardown', this.handleTeardown)
@@ -54,6 +55,7 @@ class RunStatus extends EventEmitter {
.on('stdout', this.handleOutput.bind(this, 'stdout'))
.on('stderr', this.handleOutput.bind(this, 'stderr'));
}
+
handleRejections(data) {
this.rejectionCount += data.rejections.length;
@@ -64,6 +66,7 @@ class RunStatus extends EventEmitter {
this.errors.push(err);
});
}
+
handleExceptions(data) {
this.exceptionCount++;
const err = data.exception;
@@ -72,10 +75,12 @@ class RunStatus extends EventEmitter {
this.emit('error', err, this);
this.errors.push(err);
}
+
handleTeardown(data) {
this.emit('dependencies', data.file, data.dependencies, this);
this.emit('touchedFiles', data.touchedFiles);
}
+
handleStats(stats) {
this.emit('stats', stats, this);
@@ -85,6 +90,7 @@ class RunStatus extends EventEmitter {
this.testCount += stats.testCount;
}
+
handleTest(test) {
test.title = this.prefixTitle(test.file) + test.title;
@@ -98,6 +104,7 @@ class RunStatus extends EventEmitter {
this.emit('test', test, this);
}
+
prefixTitle(file) {
if (!this.prefixTitles) {
return '';
@@ -107,9 +114,11 @@ class RunStatus extends EventEmitter {
return prefixTitle(file, this.base, separator);
}
+
handleOutput(channel, data) {
this.emit(channel, data, this);
}
+
processResults(results) {
// Assemble stats from all tests
this.stats = results.map(result => result.stats);
diff --git a/node_modules/ava/lib/runner.js b/node_modules/ava/lib/runner.js
index bda2132fd..eb02dde45 100644
--- a/node_modules/ava/lib/runner.js
+++ b/node_modules/ava/lib/runner.js
@@ -52,6 +52,7 @@ class Runner extends EventEmitter {
this.projectDir = options.projectDir;
this.serial = options.serial;
this.updateSnapshots = options.updateSnapshots;
+ this.snapshotDir = options.snapshotDir;
this.hasStarted = false;
this.results = [];
@@ -112,7 +113,7 @@ class Runner extends EventEmitter {
}
if (metadata.type === 'test' && this.match.length > 0) {
- metadata.exclusive = title !== null && matcher([title], this.match).length === 1;
+ metadata.exclusive = matcher([title || ''], this.match).length === 1;
}
const validationError = validateTest(title, fn, metadata);
@@ -130,6 +131,7 @@ class Runner extends EventEmitter {
addTestResult(result) {
const test = result.result;
const props = {
+ logs: test.logs,
duration: test.duration,
title: test.title,
error: result.reason,
@@ -183,6 +185,8 @@ class Runner extends EventEmitter {
compareTestSnapshot(options) {
if (!this.snapshots) {
this.snapshots = snapshotManager.load({
+ file: this.file,
+ fixedLocation: this.snapshotDir,
name: path.basename(this.file),
projectDir: this.projectDir,
relFile: path.relative(this.projectDir, this.file),
@@ -219,6 +223,7 @@ class Runner extends EventEmitter {
});
return Bluebird.try(() => this.tests.build().run());
}
+
attributeLeakedError(err) {
return this.tests.attributeLeakedError(err);
}
diff --git a/node_modules/ava/lib/serialize-error.js b/node_modules/ava/lib/serialize-error.js
index 55717e161..13146ff42 100644
--- a/node_modules/ava/lib/serialize-error.js
+++ b/node_modules/ava/lib/serialize-error.js
@@ -4,7 +4,6 @@ const cleanYamlObject = require('clean-yaml-object');
const StackUtils = require('stack-utils');
const assert = require('./assert');
const beautifyStack = require('./beautify-stack');
-const extractStack = require('./extract-stack');
function isAvaAssertionError(source) {
return source instanceof assert.AssertionError;
@@ -20,7 +19,7 @@ function extractSource(stack) {
return null;
}
- const firstStackLine = extractStack(stack).split('\n')[0];
+ const firstStackLine = stack.split('\n')[0];
return stackUtils.parseLine(firstStackLine);
}
function buildSource(source) {
@@ -90,5 +89,11 @@ module.exports = error => {
}
}
+ if (typeof error.stack === 'string') {
+ retval.summary = error.stack.split('\n')[0];
+ } else {
+ retval.summary = JSON.stringify(error);
+ }
+
return retval;
};
diff --git a/node_modules/ava/lib/snapshot-manager.js b/node_modules/ava/lib/snapshot-manager.js
index ea1246585..fcc24922e 100644
--- a/node_modules/ava/lib/snapshot-manager.js
+++ b/node_modules/ava/lib/snapshot-manager.js
@@ -11,6 +11,7 @@ const indentString = require('indent-string');
const makeDir = require('make-dir');
const md5Hex = require('md5-hex');
const Buffer = require('safe-buffer').Buffer;
+const convertSourceMap = require('convert-source-map');
const concordanceOptions = require('./concordance-options').snapshotManager;
@@ -355,18 +356,39 @@ class Manager {
}
}
-function determineSnapshotDir(projectDir, testDir) {
- const parts = new Set(path.relative(projectDir, testDir).split(path.sep));
+function determineSnapshotDir(options) {
+ const testDir = determineSourceMappedDir(options);
+ if (options.fixedLocation) {
+ const relativeTestLocation = path.relative(options.projectDir, testDir);
+ return path.join(options.fixedLocation, relativeTestLocation);
+ }
+
+ const parts = new Set(path.relative(options.projectDir, testDir).split(path.sep));
if (parts.has('__tests__')) {
return path.join(testDir, '__snapshots__');
- } else if (parts.has('test') || parts.has('tests')) { // Accept tests, even though it's not in the default test patterns
+ }
+ if (parts.has('test') || parts.has('tests')) { // Accept tests, even though it's not in the default test patterns
return path.join(testDir, 'snapshots');
}
+
return testDir;
}
+function determineSourceMappedDir(options) {
+ const source = tryRead(options.file).toString();
+ const converter = convertSourceMap.fromSource(source) || convertSourceMap.fromMapFileSource(source, options.testDir);
+ if (converter) {
+ const map = converter.toObject();
+ const firstSource = `${map.sourceRoot || ''}${map.sources[0]}`;
+ const sourceFile = path.resolve(options.testDir, firstSource);
+ return path.dirname(sourceFile);
+ }
+
+ return options.testDir;
+}
+
function load(options) {
- const dir = determineSnapshotDir(options.projectDir, options.testDir);
+ const dir = determineSnapshotDir(options);
const reportFile = `${options.name}.md`;
const snapFile = `${options.name}.snap`;
const snapPath = path.join(dir, snapFile);
diff --git a/node_modules/ava/lib/test-collection.js b/node_modules/ava/lib/test-collection.js
index 91c604e06..fd34bc489 100644
--- a/node_modules/ava/lib/test-collection.js
+++ b/node_modules/ava/lib/test-collection.js
@@ -33,6 +33,7 @@ class TestCollection extends EventEmitter {
this._emitTestResult = this._emitTestResult.bind(this);
}
+
add(test) {
const metadata = test.metadata;
const type = metadata.type;
@@ -91,6 +92,7 @@ class TestCollection extends EventEmitter {
this.tests.concurrent.push(test);
}
}
+
_skippedTest(test) {
return {
run: () => {
@@ -103,10 +105,12 @@ class TestCollection extends EventEmitter {
}
};
}
+
_emitTestResult(result) {
this.pendingTestInstances.delete(result.result);
this.emit('test', result);
}
+
_buildHooks(hooks, testTitle, context) {
return hooks.map(hook => {
const test = this._buildHook(hook, testTitle, context);
@@ -118,6 +122,7 @@ class TestCollection extends EventEmitter {
return test;
});
}
+
_buildHook(hook, testTitle, contextRef) {
let title = hook.title;
@@ -141,6 +146,7 @@ class TestCollection extends EventEmitter {
this.pendingTestInstances.add(test);
return test;
}
+
_buildTest(test, contextRef) {
if (!contextRef) {
contextRef = null;
@@ -158,6 +164,7 @@ class TestCollection extends EventEmitter {
this.pendingTestInstances.add(test);
return test;
}
+
_buildTestWithHooks(test) {
if (test.metadata.skipped || test.metadata.todo) {
return new Sequence([this._skippedTest(this._buildTest(test))], true);
@@ -175,24 +182,41 @@ class TestCollection extends EventEmitter {
}
return sequence;
}
+
_buildTests(tests) {
return tests.map(test => this._buildTestWithHooks(test));
}
- build() {
- const beforeHooks = new Sequence(this._buildHooks(this.hooks.before));
- const afterHooks = new Sequence(this._buildHooks(this.hooks.after));
+ _hasUnskippedTests() {
+ return this.tests.serial.concat(this.tests.concurrent)
+ .some(test => {
+ return !(test.metadata && test.metadata.skipped === true);
+ });
+ }
+
+ build() {
const serialTests = new Sequence(this._buildTests(this.tests.serial), this.bail);
const concurrentTests = new Concurrent(this._buildTests(this.tests.concurrent), this.bail);
const allTests = new Sequence([serialTests, concurrentTests]);
- let finalTests = new Sequence([beforeHooks, allTests, afterHooks], true);
+ let finalTests;
+ // Only run before and after hooks when there are unskipped tests
+ if (this._hasUnskippedTests()) {
+ const beforeHooks = new Sequence(this._buildHooks(this.hooks.before));
+ const afterHooks = new Sequence(this._buildHooks(this.hooks.after));
+ finalTests = new Sequence([beforeHooks, allTests, afterHooks], true);
+ } else {
+ finalTests = new Sequence([allTests], true);
+ }
+
if (this.hooks.afterAlways.length > 0) {
const afterAlwaysHooks = new Sequence(this._buildHooks(this.hooks.afterAlways));
finalTests = new Sequence([finalTests, afterAlwaysHooks], false);
}
+
return finalTests;
}
+
attributeLeakedError(err) {
for (const test of this.pendingTestInstances) {
if (test.attributeLeakedError(err)) {
diff --git a/node_modules/ava/lib/test-worker.js b/node_modules/ava/lib/test-worker.js
index 0061775f0..84fba364e 100644
--- a/node_modules/ava/lib/test-worker.js
+++ b/node_modules/ava/lib/test-worker.js
@@ -2,7 +2,6 @@
// Check if the test is being run without AVA cli
{
- /* eslint-disable import/order */
const path = require('path');
const chalk = require('chalk');
@@ -17,22 +16,18 @@
}
}
+const currentlyUnhandled = require('currently-unhandled')();
+const isObj = require('is-obj');
+
const adapter = require('./process-adapter');
const globals = require('./globals');
const opts = adapter.opts;
globals.options = opts;
-/* eslint-enable import/order */
-const Bluebird = require('bluebird');
-const currentlyUnhandled = require('currently-unhandled')();
-const isObj = require('is-obj');
const serializeError = require('./serialize-error');
-// Bluebird specific
-Bluebird.longStackTraces();
-
-(opts.require || []).forEach(require);
+(opts.require || []).forEach(x => require(x));
adapter.installSourceMapSupport();
adapter.installPrecompilerHook();
diff --git a/node_modules/ava/lib/test.js b/node_modules/ava/lib/test.js
index 58be54d32..839101b40 100644
--- a/node_modules/ava/lib/test.js
+++ b/node_modules/ava/lib/test.js
@@ -71,6 +71,7 @@ class ExecutionContext {
_throwsArgStart(assertion, file, line) {
this._test.trackThrows({assertion, file, line});
}
+
_throwsArgEnd() {
this._test.trackThrows(null);
}
@@ -78,6 +79,10 @@ class ExecutionContext {
{
const assertions = assert.wrapAssertions({
+ log(executionContext, text) {
+ executionContext._test.addLog(text);
+ },
+
pass(executionContext) {
executionContext._test.countPassedAssertion();
},
@@ -108,6 +113,7 @@ class Test {
this.metadata = options.metadata;
this.onResult = options.onResult;
this.title = options.title;
+ this.logs = [];
this.snapshotInvocationCount = 0;
this.compareWithSnapshot = assertionOptions => {
@@ -175,6 +181,10 @@ class Test {
this.assertCount++;
}
+ addLog(text) {
+ this.logs.push(text);
+ }
+
addPendingAssertion(promise) {
if (this.finishing) {
this.saveFirstError(new Error('Assertion passed, but test has already finished'));
diff --git a/node_modules/ava/lib/watcher.js b/node_modules/ava/lib/watcher.js
index c90c810f0..3f5ed3ee7 100644
--- a/node_modules/ava/lib/watcher.js
+++ b/node_modules/ava/lib/watcher.js
@@ -25,6 +25,7 @@ class Debouncer {
this.timer = null;
this.repeat = false;
}
+
debounce(delay) {
if (this.timer) {
this.again = true;
@@ -55,6 +56,7 @@ class Debouncer {
this.timer = timer;
}
+
cancel() {
if (this.timer) {
clearTimeout(this.timer);
@@ -69,6 +71,7 @@ class TestDependency {
this.file = file;
this.sources = sources;
}
+
contains(source) {
return this.sources.indexOf(source) !== -1;
}
@@ -146,6 +149,7 @@ class Watcher {
this.watchFiles();
this.rerunAll();
}
+
watchFiles() {
const patterns = this.avaFiles.getChokidarPatterns();
@@ -160,16 +164,18 @@ class Watcher {
}
});
}
+
trackTestDependencies(api) {
const relative = absPath => nodePath.relative(process.cwd(), absPath);
api.on('test-run', runStatus => {
runStatus.on('dependencies', (file, dependencies) => {
- const sourceDeps = dependencies.map(relative).filter(this.avaFiles.isSource);
+ const sourceDeps = dependencies.map(x => relative(x)).filter(this.avaFiles.isSource);
this.updateTestDependencies(file, sourceDeps);
});
});
}
+
updateTestDependencies(file, sources) {
if (sources.length === 0) {
this.testDependencies = this.testDependencies.filter(dep => dep.file !== file);
@@ -190,6 +196,7 @@ class Watcher {
this.testDependencies.push(new TestDependency(file, sources));
}
}
+
trackTouchedFiles(api) {
api.on('test-run', runStatus => {
runStatus.on('touchedFiles', files => {
@@ -199,11 +206,13 @@ class Watcher {
});
});
}
+
trackExclusivity(api) {
api.on('stats', stats => {
this.updateExclusivity(stats.file, stats.hasExclusive);
});
}
+
updateExclusivity(file, hasExclusiveTests) {
const index = this.filesWithExclusiveTests.indexOf(file);
@@ -213,6 +222,7 @@ class Watcher {
this.filesWithExclusiveTests.splice(index, 1);
}
}
+
trackFailures(api) {
api.on('test-run', (runStatus, files) => {
files.forEach(file => {
@@ -230,9 +240,11 @@ class Watcher {
});
});
}
+
pruneFailures(file) {
this.filesWithFailures = this.filesWithFailures.filter(state => state.file !== file);
}
+
countFailure(file, vector) {
const isUpdate = this.filesWithFailures.some(state => {
if (state.file !== file) {
@@ -251,6 +263,7 @@ class Watcher {
});
}
}
+
sumPreviousFailures(beforeVector) {
let total = 0;
@@ -262,6 +275,7 @@ class Watcher {
return total;
}
+
cleanUnlinkedTests(unlinkedTests) {
unlinkedTests.forEach(testFile => {
this.updateTestDependencies(testFile, []);
@@ -269,6 +283,7 @@ class Watcher {
this.pruneFailures(testFile);
});
}
+
observeStdin(stdin) {
stdin.resume();
stdin.setEncoding('utf8');
@@ -295,14 +310,17 @@ class Watcher {
});
});
}
+
rerunAll() {
this.dirtyStates = {};
this.run();
}
+
updatePreviousSnapshots() {
this.dirtyStates = {};
this.run(this.previousFiles, true);
}
+
runAfterChanges() {
const dirtyStates = this.dirtyStates;
this.dirtyStates = {};
diff --git a/node_modules/ava/node_modules/chalk/index.js b/node_modules/ava/node_modules/chalk/index.js
index 4c81d6d20..05e62b346 100644
--- a/node_modules/ava/node_modules/chalk/index.js
+++ b/node_modules/ava/node_modules/chalk/index.js
@@ -58,11 +58,17 @@ for (const key of Object.keys(ansiStyles)) {
styles[key] = {
get() {
const codes = ansiStyles[key];
- return build.call(this, this._styles ? this._styles.concat(codes) : [codes], key);
+ return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
}
};
}
+styles.visible = {
+ get() {
+ return build.call(this, this._styles || [], true, 'visible');
+ }
+};
+
ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
for (const model of Object.keys(ansiStyles.color.ansi)) {
if (skipModels.has(model)) {
@@ -79,7 +85,7 @@ for (const model of Object.keys(ansiStyles.color.ansi)) {
close: ansiStyles.color.close,
closeRe: ansiStyles.color.closeRe
};
- return build.call(this, this._styles ? this._styles.concat(codes) : [codes], model);
+ return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
};
}
};
@@ -102,7 +108,7 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
close: ansiStyles.bgColor.close,
closeRe: ansiStyles.bgColor.closeRe
};
- return build.call(this, this._styles ? this._styles.concat(codes) : [codes], model);
+ return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
};
}
};
@@ -110,12 +116,13 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
const proto = Object.defineProperties(() => {}, styles);
-function build(_styles, key) {
+function build(_styles, _empty, key) {
const builder = function () {
return applyStyle.apply(builder, arguments);
};
builder._styles = _styles;
+ builder._empty = _empty;
const self = this;
@@ -167,7 +174,7 @@ function applyStyle() {
}
if (!this.enabled || this.level <= 0 || !str) {
- return str;
+ return this._empty ? '' : str;
}
// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
@@ -218,3 +225,4 @@ Object.defineProperties(Chalk.prototype, styles);
module.exports = Chalk(); // eslint-disable-line new-cap
module.exports.supportsColor = supportsColor;
+module.exports.default = module.exports; // For TypeScript
diff --git a/node_modules/ava/node_modules/chalk/package.json b/node_modules/ava/node_modules/chalk/package.json
index a25712701..69889f0cd 100644
--- a/node_modules/ava/node_modules/chalk/package.json
+++ b/node_modules/ava/node_modules/chalk/package.json
@@ -1,6 +1,6 @@
{
"name": "chalk",
- "version": "2.1.0",
+ "version": "2.3.0",
"description": "Terminal string styling done right",
"license": "MIT",
"repository": "chalk/chalk",
@@ -8,13 +8,14 @@
"node": ">=4"
},
"scripts": {
- "test": "xo && nyc ava",
+ "test": "xo && tsc --project types && nyc ava",
"bench": "matcha benchmark.js",
"coveralls": "nyc report --reporter=text-lcov | coveralls"
},
"files": [
"index.js",
- "templates.js"
+ "templates.js",
+ "types/index.d.ts"
],
"keywords": [
"color",
@@ -46,14 +47,16 @@
},
"devDependencies": {
"ava": "*",
- "coveralls": "^2.11.2",
- "execa": "^0.7.0",
+ "coveralls": "^3.0.0",
+ "execa": "^0.8.0",
"import-fresh": "^2.0.0",
"matcha": "^0.7.0",
"nyc": "^11.0.2",
- "resolve-from": "^3.0.0",
+ "resolve-from": "^4.0.0",
+ "typescript": "^2.5.3",
"xo": "*"
},
+ "types": "types/index.d.ts",
"xo": {
"envs": [
"node",
diff --git a/node_modules/ava/node_modules/chalk/readme.md b/node_modules/ava/node_modules/chalk/readme.md
index dfcfdf25d..9bb2e65e8 100644
--- a/node_modules/ava/node_modules/chalk/readme.md
+++ b/node_modules/ava/node_modules/chalk/readme.md
@@ -9,7 +9,7 @@
> Terminal string styling done right
-[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
+[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs)
### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0)
@@ -170,6 +170,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
+- `visible` (Text is emitted only if enabled)
### Colors
@@ -286,6 +287,7 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
+- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
@@ -293,6 +295,7 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i
- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
+- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings
## Maintainers
diff --git a/node_modules/ava/node_modules/chalk/templates.js b/node_modules/ava/node_modules/chalk/templates.js
index 101551528..dbdf9b221 100644
--- a/node_modules/ava/node_modules/chalk/templates.js
+++ b/node_modules/ava/node_modules/chalk/templates.js
@@ -1,28 +1,28 @@
'use strict';
-const TEMPLATE_REGEX = /(?:\\(u[a-f0-9]{4}|x[a-f0-9]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
+const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
-const ESCAPE_REGEX = /\\(u[0-9a-f]{4}|x[0-9a-f]{2}|.)|([^\\])/gi;
-
-const ESCAPES = {
- n: '\n',
- r: '\r',
- t: '\t',
- b: '\b',
- f: '\f',
- v: '\v',
- 0: '\0',
- '\\': '\\',
- e: '\u001b',
- a: '\u0007'
-};
+const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
+
+const ESCAPES = new Map([
+ ['n', '\n'],
+ ['r', '\r'],
+ ['t', '\t'],
+ ['b', '\b'],
+ ['f', '\f'],
+ ['v', '\v'],
+ ['0', '\0'],
+ ['\\', '\\'],
+ ['e', '\u001B'],
+ ['a', '\u0007']
+]);
function unescape(c) {
if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
return String.fromCharCode(parseInt(c.slice(1), 16));
}
- return ESCAPES[c] || c;
+ return ESCAPES.get(c) || c;
}
function parseArguments(name, args) {
diff --git a/node_modules/ava/package.json b/node_modules/ava/package.json
index 2cf988dd7..ffc722117 100644
--- a/node_modules/ava/package.json
+++ b/node_modules/ava/package.json
@@ -1,48 +1,17 @@
{
"name": "ava",
- "version": "0.21.0",
+ "version": "0.24.0",
"description": "Futuristic test runner 🚀",
"license": "MIT",
"repository": "avajs/ava",
"homepage": "https://ava.li",
- "author": {
- "name": "Sindre Sorhus",
- "email": "sindresorhus@gmail.com",
- "url": "sindresorhus.com"
- },
- "maintainers": [
- {
- "name": "Vadim Demedes",
- "email": "vdemedes@gmail.com",
- "url": "github.com/vadimdemedes"
- },
- {
- "name": "James Talmage",
- "email": "james@talmage.io",
- "url": "github.com/jamestalmage"
- },
- {
- "name": "Mark Wubben",
- "email": "mark@novemberborn.net",
- "url": "novemberborn.net"
- },
- {
- "name": "Juan Soto",
- "email": "juan@juansoto.me",
- "url": "juansoto.me"
- },
- {
- "name": "Jeroen Engels",
- "email": "jfm.engels@gmail.com",
- "url": "github.com/jfmengels"
- }
- ],
"bin": "cli.js",
"engines": {
"node": ">=4"
},
"scripts": {
- "test": "xo && flow check test/flow-types && tsc -p test/ts-types && nyc tap --no-cov --timeout=300 --jobs=4 test/*.js test/reporters/*.js",
+ "lint": "xo && (cd test/fixture && xo '**' '!{source-map-initial,syntax-error}.js' '!snapshots/test-sourcemaps/build/**') && lock-verify",
+ "test": "npm run lint && flow check test/flow-types && tsc -p test/ts-types && nyc tap --no-cov --timeout=300 --jobs=4 test/*.js test/reporters/*.js",
"test-win": "tap --no-cov --reporter=classic --timeout=300 --jobs=4 test/*.js test/reporters/*.js",
"visual": "node test/visual/run-visual-tests.js",
"prepublish": "npm run make-ts",
@@ -75,7 +44,6 @@
"babel",
"assert",
"assertion",
- "futuristic",
"promise",
"promises",
"async",
@@ -85,8 +53,8 @@
"generators",
"yield",
"observable",
- "unit",
"observables",
+ "unit",
"snapshot",
"expect",
"typescript",
@@ -97,7 +65,7 @@
"@ava/babel-preset-transform-test-files": "^3.0.0",
"@ava/write-file-atomic": "^2.2.0",
"@concordance/react": "^1.0.0",
- "ansi-escapes": "^2.0.0",
+ "ansi-escapes": "^3.0.0",
"ansi-styles": "^3.1.0",
"arr-flatten": "^1.0.1",
"array-union": "^1.0.1",
@@ -106,6 +74,8 @@
"auto-bind": "^1.1.0",
"ava-init": "^0.2.0",
"babel-core": "^6.17.0",
+ "babel-generator": "^6.26.0",
+ "babel-plugin-syntax-object-rest-spread": "^6.13.0",
"bluebird": "^3.0.0",
"caching-transform": "^1.0.0",
"chalk": "^2.0.1",
@@ -122,7 +92,7 @@
"convert-source-map": "^1.2.0",
"core-assert": "^0.2.0",
"currently-unhandled": "^0.4.1",
- "debug": "^2.2.0",
+ "debug": "^3.0.1",
"dot-prop": "^4.1.0",
"empower-core": "^0.6.1",
"equal-length": "^1.0.0",
@@ -139,7 +109,7 @@
"is-ci": "^1.0.7",
"is-generator-fn": "^1.0.0",
"is-obj": "^1.0.0",
- "is-observable": "^0.2.0",
+ "is-observable": "^1.0.0",
"is-promise": "^2.1.0",
"js-yaml": "^3.8.2",
"last-line-stream": "^1.0.0",
@@ -159,47 +129,49 @@
"package-hash": "^2.0.0",
"pkg-conf": "^2.0.0",
"plur": "^2.0.0",
- "pretty-ms": "^2.0.0",
+ "pretty-ms": "^3.0.0",
"require-precompiled": "^0.1.0",
"resolve-cwd": "^2.0.0",
"safe-buffer": "^5.1.1",
+ "semver": "^5.4.1",
"slash": "^1.0.0",
- "source-map-support": "^0.4.0",
- "stack-utils": "^1.0.0",
+ "source-map-support": "^0.5.0",
+ "stack-utils": "^1.0.1",
"strip-ansi": "^4.0.0",
"strip-bom-buf": "^1.0.0",
- "supports-color": "^4.0.0",
+ "supports-color": "^5.0.0",
"time-require": "^0.1.2",
"trim-off-newlines": "^1.0.1",
"unique-temp-dir": "^1.0.0",
- "update-notifier": "^2.1.0"
+ "update-notifier": "^2.3.0"
},
"devDependencies": {
"cli-table2": "^0.2.0",
- "codecov": "^2.1.0",
+ "codecov": "^3.0.0",
"del": "^3.0.0",
"delay": "^2.0.0",
- "execa": "^0.7.0",
- "flow-bin": "^0.49.1",
+ "execa": "^0.8.0",
+ "flow-bin": "^0.59.0",
"get-stream": "^3.0.0",
"git-branch": "^1.0.0",
"has-ansi": "^3.0.0",
- "inquirer": "^3.0.5",
+ "inquirer": "^4.0.0",
"is-array-sorted": "^1.0.0",
- "lolex": "^1.4.0",
+ "lock-verify": "^1.1.0",
+ "lolex": "^2.1.2",
"nyc": "^11.0.3",
"proxyquire": "^1.7.4",
- "react": "^15.6.1",
- "react-test-renderer": "^15.6.1",
+ "react": "^16.1.1",
+ "react-test-renderer": "^16.1.1",
"signal-exit": "^3.0.0",
- "sinon": "^2.0.0",
+ "sinon": "^4.1.2",
"source-map-fixtures": "^2.1.0",
"tap": "^10.0.0",
"temp-write": "^3.1.0",
- "touch": "^2.0.2",
+ "touch": "^3.1.0",
"typescript": "^2.2.2",
"xo": "^0.18.2",
- "zen-observable": "^0.5.1"
+ "zen-observable": "^0.6.0"
},
"typings": "types/generated.d.ts",
"xo": {
diff --git a/node_modules/ava/readme.md b/node_modules/ava/readme.md
index 239f257a4..825e83253 100644
--- a/node_modules/ava/readme.md
+++ b/node_modules/ava/readme.md
@@ -2,7 +2,7 @@
> Futuristic test runner
-[![Build Status: Linux](https://travis-ci.org/avajs/ava.svg?branch=master)](https://travis-ci.org/avajs/ava) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/e7v91mu2m5x48ehx/branch/master?svg=true)](https://ci.appveyor.com/project/ava/ava/branch/master) [![Coverage Status](https://coveralls.io/repos/github/avajs/ava/badge.svg?branch=master)](https://coveralls.io/github/avajs/ava?branch=master) [![Dependency Status](https://dependencyci.com/github/avajs/ava/badge)](https://dependencyci.com/github/avajs/ava) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![Gitter](https://badges.gitter.im/join_chat.svg)](https://gitter.im/avajs/ava)
+[![Build Status: Linux](https://travis-ci.org/avajs/ava.svg?branch=master)](https://travis-ci.org/avajs/ava) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/e7v91mu2m5x48ehx/branch/master?svg=true)](https://ci.appveyor.com/project/ava/ava/branch/master) [![Coverage Status](https://coveralls.io/repos/github/avajs/ava/badge.svg?branch=master)](https://coveralls.io/github/avajs/ava?branch=master) [![Dependency Status](https://dependencyci.com/github/avajs/ava/badge)](https://dependencyci.com/github/avajs/ava) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![Gitter](https://badges.gitter.im/join_chat.svg)](https://gitter.im/avajs/ava) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs)
Even though JavaScript is single-threaded, IO in Node.js can happen in parallel due to its async nature. AVA takes advantage of this and runs your tests concurrently, which is especially beneficial for IO heavy tests. In addition, test files are run in parallel as separate processes, giving you even better performance and an isolated environment for each test file. [Switching](https://github.com/sindresorhus/pageres/commit/663be15acb3dd2eb0f71b1956ef28c2cd3fdeed0) from Mocha to AVA in Pageres brought the test time down from 31 to 11 seconds. Having tests run concurrently forces you to write atomic tests, meaning tests don't depend on global state or the state of other tests, which is a great thing!
@@ -69,18 +69,18 @@ test(t => {
### Add AVA to your project
-Install AVA globally and run it with `--init` to add AVA to your `package.json`. [Yarn](https://yarnpkg.com/) currently provides significant speed improvements over npm during the installation process. Consider [using Yarn](https://yarnpkg.com/en/docs/install) if the installation is too slow for your needs.
+Install AVA globally and run it with `--init` to add AVA to your `package.json`.
```console
-$ yarn global add ava
+$ npm install --global ava
$ ava --init
```
-If you prefer using npm:
+If you prefer using Yarn:
```console
-$ npm install --global ava
+$ yarn global add ava
$ ava --init
```
@@ -105,13 +105,13 @@ Any arguments passed after `--init` are added as config to `package.json`.
You can also install AVA directly:
```console
-$ yarn add --dev ava
+$ npm install --save-dev ava
```
-Alternatively using npm:
+Alternatively using Yarn:
```console
-$ npm install --save-dev ava
+$ yarn add --dev ava
```
You'll have to configure the `test` script in your `package.json` to use `ava` (see above).
@@ -169,7 +169,7 @@ $ ava --help
--match, -m Only run tests with matching title (Can be repeated)
--watch, -w Re-run tests when tests and source files change
--timeout, -T Set global timeout
- --concurrency, -c Maximum number of test files running at the same time (EXPERIMENTAL)
+ --concurrency, -c Max number of test files running at the same time (Default: CPU cores)
--update-snapshots, -u Update snapshots
Examples
@@ -277,7 +277,20 @@ All of the CLI options can be configured in the `ava` section of your `package.j
Arguments passed to the CLI will always take precedence over the configuration in `package.json`.
-See the [ES2017 support](#es2017-support) section for details on the `babel` option.
+### Options
+
+- `files`: file & directory paths and glob patterns that select which files AVA will run tests from. Only files with a `.js` extension are used. Files with an underscore prefix are ignored. All `.js` files in selected directories are run
+- `source`: files that, when changed, cause tests to be re-run in watch mode. See the [watch mode recipe for details](https://github.com/avajs/ava/blob/master/docs/recipes/watch-mode.md#source-files-and-test-files)
+- `match`: not typically useful in the `package.json` configuration, but equivalent to [specifying `--match` on the CLI](#running-tests-with-matching-titles)
+- `failFast`: stop running further tests once a test fails
+- `failWithoutAssertions`: if `false`, does not fail a test if it doesn't run [assertions](#assertions)
+- `tap`: if `true`, enables the [TAP reporter](#tap-reporter)
+- `snapshotDir`: specifies a fixed location for storing snapshot files. Use this if your snapshots are ending up in the wrong location
+- `powerAssert`: if `false`, disables [power-assert](https://github.com/power-assert-js/power-assert) which otherwise helps provide more descriptive error messages
+- `require`: extra modules to require before tests are run. Modules are required in the [worker processes](#process-isolation)
+- `babel`: test file specific Babel options. See [ES2017 support](#es2017-support) for more details
+
+Note that providing files on the CLI overrides the `files` option. If you've configured a glob pattern, for instance `test/**/*.test.js`, you may want to repeat it when using the CLI: `ava 'test/integration/*.test.js'`.
## Documentation
@@ -400,7 +413,7 @@ test.only('will be run', t => {
});
```
-`.only` applies across all test files, so if you use it in one file, no tests from the other file will run.
+*Note:* The `.only` modifier applies to the test file it's defined in, so if you run multiple test files, tests in other files will still run. If you want to only run the `test.only` test, provide just that test file to AVA.
### Running tests with matching titles
@@ -513,10 +526,12 @@ test.failing('demonstrate some bug', t => {
AVA lets you register hooks that are run before and after your tests. This allows you to run setup and/or teardown code.
-`test.before()` registers a hook to be run before the first test in your test file. Similarly `test.after()` registers a hook to be run after the last test. Use `test.after.always()` to register a hook that will **always** run once your tests and other hooks complete. `.always()` hooks run regardless of whether there were earlier failures, so they are ideal for cleanup tasks. There are two exceptions to this however. If you use `--fail-fast` AVA will stop testing as soon as a failure occurs, and it won't run any hooks including the `.always()` hooks. Uncaught exceptions will crash your tests, possibly preventing `.always()` hooks from running.
+`test.before()` registers a hook to be run before the first test in your test file. Similarly `test.after()` registers a hook to be run after the last test. Use `test.after.always()` to register a hook that will **always** run once your tests and other hooks complete. `.always()` hooks run regardless of whether there were earlier failures or if all tests were skipped, so they are ideal for cleanup tasks. There are two exceptions to this however. If you use `--fail-fast` AVA will stop testing as soon as a failure occurs, and it won't run any hooks including the `.always()` hooks. Uncaught exceptions will crash your tests, possibly preventing `.always()` hooks from running.
`test.beforeEach()` registers a hook to be run before each test in your test file. Similarly `test.afterEach()` a hook to be run after each test. Use `test.afterEach.always()` to register an after hook that is called even if other test hooks, or the test itself, fail. `.always()` hooks are ideal for cleanup tasks.
+If a test is skipped with the `.skip` modifier, the respective `.beforeEach()` and `.afterEach()` hooks are not run. Likewise, if all tests in a test file are skipped `.before()` and `.after()` hooks for the file are not run. Hooks modified with `.always()` will always run, even if all tests are skipped.
+
**Note**: If the `--fail-fast` flag is specified, AVA will stop after the first test failure and the `.always` hook will **not** run.
Like `test()` these methods take an optional title and a callback function. The title is shown if your hook fails to execute. The callback is called with an [execution object](#t).
@@ -875,6 +890,10 @@ Plan how many assertion there are in the test. The test will fail if the actual
End the test. Only works with `test.cb()`.
+###### `t.log(message)`
+
+Print a log message contextually alongside the test result instead of immediately printing it to `stdout` like `console.log`.
+
## Assertions
Assertions are mixed into the [execution object](#t) provided to each test implementation:
@@ -975,7 +994,7 @@ Assert that `function` does not throw an error or that `promise` does not reject
Like the `.throws()` assertion, when testing a promise you must wait for the assertion to complete:
```js
-test('rejects', async t => {
+test('resolves', async t => {
await t.notThrows(promise);
});
```
@@ -1041,6 +1060,20 @@ You can then check your code. If the change was intentional you can use the `--u
$ ava --update-snapshots
```
+You can specify a fixed location for storing the snapshot files in AVA's [`package.json` configuration](#configuration):
+
+```json
+{
+ "ava": {
+ "snapshotDir": "custom-directory"
+ }
+}
+```
+
+The snapshot files will be saved in a directory structure that mirrors that of your test files.
+
+If you are running AVA against precompiled test files, AVA will try and use source maps to determine the location of the original files. Snapshots will be stored next to these files, following the same rules as if AVA had executed the original files directly. This is great if you're writing your tests in TypeScript (see our [TypeScript recipe](docs/recipes/typescript.md)).
+
### Skipping assertions
Any assertion can be skipped using the `skip` modifier. Skipped assertions are still counted, so there is no need to change your planned assertion count.
@@ -1096,6 +1129,8 @@ t.true(a.test(b) || b === c)
Each test file is run in a separate Node.js process. This allows you to change the global state or overriding a built-in in one test file, without affecting another. It's also great for performance on modern multi-core processors, allowing multiple test files to execute in parallel.
+AVA will set `process.env.NODE_ENV` to `test`, unless the `NODE_ENV` environment variable has been set. This is useful if the code you're testing has test defaults (for example when picking what database to connect to, or environment-specific Babel options). It may cause your code or its dependencies to behave differently though. Note that `'NODE_ENV' in process.env` will always be `true`.
+
## Tips
### Temp files
@@ -1178,7 +1213,7 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
## Team
-[![Sindre Sorhus](https://avatars.githubusercontent.com/u/170270?s=130)](http://sindresorhus.com) | [![Vadim Demedes](https://avatars.githubusercontent.com/u/697676?s=130)](https://github.com/vadimdemedes) | [![James Talmage](https://avatars.githubusercontent.com/u/4082216?s=130)](https://github.com/jamestalmage) | [![Mark Wubben](https://avatars.githubusercontent.com/u/33538?s=130)](https://novemberborn.net) | [![Juan Soto](https://avatars.githubusercontent.com/u/8217766?s=130)](https://juansoto.me) | [![Jeroen Engels](https://avatars.githubusercontent.com/u/3869412?s=130)](https://github.com/jfmengels)
+[![Sindre Sorhus](https://github.com/sindresorhus.png?size=100)](https://github.com/sindresorhus) | [![Vadim Demedes](https://github.com/vadimdemedes.png?size=100)](https://github.com/vadimdemedes) | [![James Talmage](https://github.com/jamestalmage.png?size=100)](https://github.com/jamestalmage) | [![Mark Wubben](https://github.com/novemberborn.png?size=100)](https://github.com/novemberborn) | [![Juan Soto](https://github.com/sotojuan.png?size=100)](https://github.com/sotojuan) | [![Jeroen Engels](https://github.com/jfmengels.png?size=100)](https://github.com/jfmengels)
---|---|---|---|---|---
[Sindre Sorhus](http://sindresorhus.com) | [Vadim Demedes](https://github.com/vadimdemedes) | [James Talmage](https://github.com/jamestalmage) | [Mark Wubben](https://novemberborn.net) | [Juan Soto](http://juansoto.me) | [Jeroen Engels](https://github.com/jfmengels)
diff --git a/node_modules/ava/types/generated.d.ts b/node_modules/ava/types/generated.d.ts
index 85003c0cf..19cbc0a02 100644
--- a/node_modules/ava/types/generated.d.ts
+++ b/node_modules/ava/types/generated.d.ts
@@ -89,12 +89,20 @@ export interface AssertContext {
}
export interface TestContext extends AssertContext {
/**
+ * Test title.
+ */
+ title: string;
+ /**
* Plan how many assertion there are in the test.
* The test will fail if the actual assertion count doesn't match planned assertions.
*/
plan(count: number): void;
skip: AssertContext;
+ /**
+ * Print a log message contextually alongside the test result instead of immediately printing it to stdout like console.log.
+ */
+ log(message: string): void;
}
export interface CallbackTestContext extends TestContext {
/**