diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 6935579b5..4b96ec216 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -41,9 +41,9 @@ We'd like to fix [`priority` issues](https://github.com/avajs/ava/labels/priorit
Read on for tips on contributing code.
-### Hang out in our chat
+### Hang out and chat
-We have a [chat](https://spectrum.chat/ava). Jump in there and lurk, talk to us, and help others.
+We're using [GitHub Discussions](https://github.com/avajs/ava/discussions). Jump in there and lurk, talk to us, and help others.
## Contributing code
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 84e12671e..ebbb4df5d 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,11 +1,7 @@
blank_issues_enabled: true
contact_links:
+ - name: Questions? Ideas? Something to share?
+ url: https://github.com/avajs/ava/discussions
- name: Babel
url: https://github.com/avajs/babel/issues
- about: Ask about using Babel with AVA
- - name: AVA on Spectrum
- url: https://spectrum.chat/ava
- about: Ask questions and discuss in our Spectrum community
- - name: Stack Overflow
- url: https://stackoverflow.com/questions/tagged/ava
- about: Tag your question on Stack Overflow
+ about: Report a bug with AVA's Babel integration
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2da6efc0a..4320f704b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
node-version: [^10.18.0, ^12.14.0, ^14.0.0, ^15.0.0]
os: [ubuntu-latest, windows-latest]
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Enable symlinks
@@ -26,11 +26,11 @@ jobs:
run: |
git config core.symlinks true
git reset --hard
- - uses: actions/setup-node@v1
+ - uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm ci --no-audit
- - run: npm test
+ - run: npm run cover
- uses: codecov/codecov-action@v1
with:
file: coverage/lcov.info
@@ -43,10 +43,10 @@ jobs:
matrix:
ts-version: [~3.7.5, ~3.8, ~3.9, ~4.0, ~4.1]
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v2
with:
fetch-depth: 1
- - uses: actions/setup-node@v1
+ - uses: actions/setup-node@v2
with:
node-version: ^12
- run: npm ci --no-audit
@@ -60,14 +60,14 @@ jobs:
name: Test package-lock for unexpected modifications
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v2
with:
fetch-depth: 1
- - uses: actions/setup-node@v1
+ - uses: actions/setup-node@v2
with:
node-version: ^12.14.0
- name: Upgrade npm
- run: if [[ "$(npm -v)" != "6.13.4" ]]; then npm install --global npm@6.13.4; fi
+ run: if [[ "$(npm -v)" != "6.14.10" ]]; then npm install --global npm@6.14.10; fi
- run: npm ci --no-audit
- name: Test package-lock for unexpected modifications
run: |
@@ -83,11 +83,24 @@ jobs:
name: Install dependencies without using a lockfile
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v2
with:
fetch-depth: 1
- - uses: actions/setup-node@v1
+ - uses: actions/setup-node@v2
with:
node-version: ^12.14.0
- run: npm install --no-shrinkwrap --no-audit
- - run: npm test
+ - run: npm run cover
+
+ xo:
+ name: Lint source files
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 1
+ - uses: actions/setup-node@v2
+ with:
+ node-version: ^10.18.0
+ - run: npm ci
+ - run: npx xo
diff --git a/ava.config.js b/ava.config.js
index 402ed8c71..969924dd0 100644
--- a/ava.config.js
+++ b/ava.config.js
@@ -1,6 +1,7 @@
const skipTests = [];
if (process.versions.node < '12.17.0') {
skipTests.push(
+ '!test/config/next-gen.js',
'!test/configurable-module-format/module.js',
'!test/shared-workers/!(requires-newish-node)/**'
);
diff --git a/docs/06-configuration.md b/docs/06-configuration.md
index 75d9f1c08..05474a454 100644
--- a/docs/06-configuration.md
+++ b/docs/06-configuration.md
@@ -73,11 +73,13 @@ To use these files:
2. Your `package.json` must not contain an `ava` property (or, if it does, it must be an empty object)
3. You must not both have an `ava.config.js` *and* an `ava.config.cjs` file
-AVA recognizes `ava.config.mjs` files but refuses to load them.
+AVA 3 recognizes `ava.config.mjs` files but refuses to load them. This is changing in AVA 4, [see below](#next-generation-configuration).
### `ava.config.js`
-For `ava.config.js` files you must use `export default`. You cannot use ["module scope"](https://nodejs.org/docs/latest-v12.x/api/modules.html#modules_the_module_scope). You cannot import dependencies.
+In AVA 3, for `ava.config.js` files you must use `export default`. You cannot use ["module scope"](https://nodejs.org/docs/latest-v12.x/api/modules.html#modules_the_module_scope). You cannot import dependencies.
+
+This is changing in AVA 4, [see below](#next-generation-configuration).
The default export can either be a plain object or a factory function which returns a plain object:
@@ -111,7 +113,7 @@ export default ({projectDir}) => {
};
```
-Note that the final configuration must not be a promise.
+Note that the final configuration must not be a promise. This is changing in AVA 4, [see below](#next-generation-configuration).
### `ava.config.cjs`
@@ -149,12 +151,14 @@ module.exports = ({projectDir}) => {
};
```
-Note that the final configuration must not be a promise.
+Note that the final configuration must not be a promise. This is changing in AVA 4, [see below](#next-generation-configuration).
## Alternative configuration files
The [CLI] lets you specify a specific configuration file, using the `--config` flag. This file must have either a `.js` or `.cjs` extension and is processed like an `ava.config.js` or `ava.config.cjs` file would be.
+AVA 4 also supports `.mjs` extensions, [see below](#next-generation-configuration).
+
When the `--config` flag is set, the provided file will override all configuration from the `package.json` and `ava.config.js` or `ava.config.cjs` files. The configuration is not merged.
The configuration file *must* be in the same directory as the `package.json` file.
@@ -182,6 +186,25 @@ module.exports = {
You can now run your unit tests through `npx ava` and the integration tests through `npx ava --config integration-tests.config.cjs`.
+## Next generation configuration
+
+AVA 4 will add full support for ESM configuration files as well as allowing you to have asynchronous factory functions. If you're using Node.js 12 or later you can opt-in to these features in AVA 3 by enabling the `nextGenConfig` experiment. Say in an `ava.config.mjs` file:
+
+```js
+export default {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ files: ['unit-tests/**/*]
+};
+```
+
+This also allows you to pass an `.mjs` file using the `--config` argument.
+
+With this experiment enabled, AVA will no longer have special treatment for `ava.config.js` files. Instead AVA follows Node.js' behavior, so if you've set [`"type": "module"`](https://nodejs.org/docs/latest/api/packages.html#packages_type) you must use ESM, and otherwise you must use CommonJS.
+
+You mustn't have an `ava.config.mjs` file next to an `ava.config.js` or `ava.config.cjs` file.
+
## Object printing depth
By default, AVA prints nested objects to a depth of `3`. However, when debugging tests with deeply nested objects, it can be useful to print with more detail. This can be done by setting [`util.inspect.defaultOptions.depth`](https://nodejs.org/api/util.html#util_util_inspect_defaultoptions) to the desired depth, before the test is executed:
diff --git a/eslint-plugin-helper.js b/eslint-plugin-helper.js
index b327e25b0..b8e4a71ec 100644
--- a/eslint-plugin-helper.js
+++ b/eslint-plugin-helper.js
@@ -1,26 +1,25 @@
'use strict';
-const normalizeExtensions = require('./lib/extensions');
+let isMainThread = true;
+let supportsWorkers = false;
+try {
+ ({isMainThread} = require('worker_threads'));
+ supportsWorkers = true;
+} catch {}
+
const {classify, hasExtension, isHelperish, matches, normalizeFileForMatching, normalizeGlobs, normalizePatterns} = require('./lib/globs');
-const loadConfig = require('./lib/load-config');
-const providerManager = require('./lib/provider-manager');
-const configCache = new Map();
-const helperCache = new Map();
+let resolveGlobs;
+let resolveGlobsSync;
-function load(projectDir, overrides) {
- const cacheKey = `${JSON.stringify(overrides)}\n${projectDir}`;
- if (helperCache.has(cacheKey)) {
- return helperCache.get(cacheKey);
- }
+if (!supportsWorkers || !isMainThread) {
+ const normalizeExtensions = require('./lib/extensions');
+ const {loadConfig, loadConfigSync} = require('./lib/load-config');
+ const providerManager = require('./lib/provider-manager');
- let conf;
- let providers;
- if (configCache.has(projectDir)) {
- ({conf, providers} = configCache.get(projectDir));
- } else {
- conf = loadConfig({resolveFrom: projectDir});
+ const configCache = new Map();
- providers = [];
+ const collectProviders = ({conf, projectDir}) => {
+ const providers = [];
if (Reflect.has(conf, 'babel')) {
const {level, main} = providerManager.babel(projectDir);
providers.push({
@@ -39,12 +38,125 @@ function load(projectDir, overrides) {
});
}
- configCache.set(projectDir, {conf, providers});
+ return providers;
+ };
+
+ const buildGlobs = ({conf, providers, projectDir, overrideExtensions, overrideFiles}) => {
+ const extensions = overrideExtensions ?
+ normalizeExtensions(overrideExtensions) :
+ normalizeExtensions(conf.extensions, providers);
+
+ return {
+ cwd: projectDir,
+ ...normalizeGlobs({
+ extensions,
+ files: overrideFiles ? overrideFiles : conf.files,
+ providers
+ })
+ };
+ };
+
+ resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => {
+ if (!configCache.has(projectDir)) {
+ const conf = loadConfigSync({resolveFrom: projectDir});
+ const providers = collectProviders({conf, projectDir});
+ configCache.set(projectDir, {conf, providers});
+ }
+
+ const {conf, providers} = configCache.get(projectDir);
+ return buildGlobs({conf, providers, projectDir, overrideExtensions, overrideFiles});
+ };
+
+ resolveGlobs = async (projectDir, overrideExtensions, overrideFiles) => {
+ if (!configCache.has(projectDir)) {
+ configCache.set(projectDir, loadConfig({resolveFrom: projectDir}).then(conf => { // eslint-disable-line promise/prefer-await-to-then
+ const providers = collectProviders({conf, projectDir});
+ return {conf, providers};
+ }));
+ }
+
+ const {conf, providers} = await configCache.get(projectDir);
+ return buildGlobs({conf, providers, projectDir, overrideExtensions, overrideFiles});
+ };
+}
+
+if (supportsWorkers) {
+ const v8 = require('v8');
+
+ const MAX_DATA_LENGTH_EXCLUSIVE = 100 * 1024; // Allocate 100 KiB to exchange globs.
+
+ if (isMainThread) {
+ const {Worker} = require('worker_threads');
+ let data;
+ let sync;
+ let worker;
+
+ resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => {
+ if (worker === undefined) {
+ const dataBuffer = new SharedArrayBuffer(MAX_DATA_LENGTH_EXCLUSIVE);
+ data = new Uint8Array(dataBuffer);
+
+ const syncBuffer = new SharedArrayBuffer(4);
+ sync = new Int32Array(syncBuffer);
+
+ worker = new Worker(__filename, {
+ workerData: {
+ dataBuffer,
+ syncBuffer,
+ firstMessage: {projectDir, overrideExtensions, overrideFiles}
+ }
+ });
+ worker.unref();
+ } else {
+ worker.postMessage({projectDir, overrideExtensions, overrideFiles});
+ }
+
+ Atomics.wait(sync, 0, 0);
+
+ const byteLength = Atomics.exchange(sync, 0, 0);
+ if (byteLength === MAX_DATA_LENGTH_EXCLUSIVE) {
+ throw new Error('Globs are over 100 KiB and cannot be resolved');
+ }
+
+ const globsOrError = v8.deserialize(data.slice(0, byteLength));
+ if (globsOrError instanceof Error) {
+ throw globsOrError;
+ }
+
+ return globsOrError;
+ };
+ } else {
+ const {parentPort, workerData} = require('worker_threads');
+ const data = new Uint8Array(workerData.dataBuffer);
+ const sync = new Int32Array(workerData.syncBuffer);
+
+ const handleMessage = async ({projectDir, overrideExtensions, overrideFiles}) => {
+ let encoded;
+ try {
+ const globs = await resolveGlobs(projectDir, overrideExtensions, overrideFiles);
+ encoded = v8.serialize(globs);
+ } catch (error) {
+ encoded = v8.serialize(error);
+ }
+
+ const byteLength = encoded.length < MAX_DATA_LENGTH_EXCLUSIVE ? encoded.copy(data) : MAX_DATA_LENGTH_EXCLUSIVE;
+ Atomics.store(sync, 0, byteLength);
+ Atomics.notify(sync, 0);
+ };
+
+ parentPort.on('message', handleMessage);
+ handleMessage(workerData.firstMessage);
+ delete workerData.firstMessage;
}
+}
+
+const helperCache = new Map();
- const extensions = overrides && overrides.extensions ?
- normalizeExtensions(overrides.extensions) :
- normalizeExtensions(conf.extensions, providers);
+function load(projectDir, overrides) {
+ const cacheKey = `${JSON.stringify(overrides)}\n${projectDir}`;
+ if (helperCache.has(cacheKey)) {
+ return helperCache.get(cacheKey);
+ }
let helperPatterns = [];
if (overrides && overrides.helpers !== undefined) {
@@ -55,14 +167,7 @@ function load(projectDir, overrides) {
helperPatterns = normalizePatterns(overrides.helpers);
}
- const globs = {
- cwd: projectDir,
- ...normalizeGlobs({
- extensions,
- files: overrides && overrides.files ? overrides.files : conf.files,
- providers
- })
- };
+ const globs = resolveGlobsSync(projectDir, overrides && overrides.extensions, overrides && overrides.files);
const classifyForESLint = file => {
const {isTest} = classify(file, globs);
diff --git a/lib/api.js b/lib/api.js
index 12bf420d3..14d2a7200 100644
--- a/lib/api.js
+++ b/lib/api.js
@@ -111,10 +111,8 @@ class Api extends Emittery {
}
};
- let cacheDir;
let testFiles;
try {
- cacheDir = this._createCacheDir();
testFiles = await globs.findTests({cwd: this.options.projectDir, ...apiOptions.globs});
if (selectedFiles.length === 0) {
selectedFiles = filter.length === 0 ? testFiles : globs.applyTestFileFilter({
@@ -189,7 +187,7 @@ class Api extends Emittery {
const {providers = []} = this.options;
const providerStates = (await Promise.all(providers.map(async ({type, main}) => {
- const state = await main.compile({cacheDir, files: testFiles});
+ const state = await main.compile({cacheDir: this._createCacheDir(), files: testFiles});
return state === null ? null : {type, state};
}))).filter(state => state !== null);
diff --git a/lib/cli.js b/lib/cli.js
index f98c713bb..e591a6643 100644
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -7,7 +7,7 @@ const arrify = require('arrify');
const yargs = require('yargs');
const readPkg = require('read-pkg');
const isCi = require('./is-ci');
-const loadConfig = require('./load-config');
+const {loadConfig} = require('./load-config');
function exit(message) {
console.error(`\n ${require('./chalk').get().red(figures.cross)} ${message}`);
@@ -83,7 +83,7 @@ exports.run = async () => { // eslint-disable-line complexity
let confError = null;
try {
const {argv: {config: configFile}} = yargs.help(false);
- conf = loadConfig({configFile});
+ conf = await loadConfig({configFile});
} catch (error) {
confError = error;
}
diff --git a/lib/load-config.js b/lib/load-config.js
index d8076d4d2..198a74207 100644
--- a/lib/load-config.js
+++ b/lib/load-config.js
@@ -1,6 +1,7 @@
'use strict';
const fs = require('fs');
const path = require('path');
+const url = require('url');
const vm = require('vm');
const {isPlainObject} = require('is-plain-object');
const pkgConf = require('pkg-conf');
@@ -11,23 +12,37 @@ const EXPERIMENTS = new Set([
'configurableModuleFormat',
'disableNullExpectations',
'disableSnapshotsInHooks',
+ 'nextGenConfig',
'reverseTeardowns',
'sharedWorkers'
]);
// *Very* rudimentary support for loading ava.config.js files containing an `export default` statement.
-const evaluateJsConfig = configFile => {
- const contents = fs.readFileSync(configFile, 'utf8');
- const script = new vm.Script(`'use strict';(()=>{let __export__;\n${contents.replace(/export default/g, '__export__ =')};return __export__;})()`, {
+const evaluateJsConfig = (contents, configFile) => {
+ const script = new vm.Script(`'use strict';(()=>{let __export__;\n${contents.toString('utf8').replace(/export default/g, '__export__ =')};return __export__;})()`, {
filename: configFile,
lineOffset: -1
});
- return {
- default: script.runInThisContext()
- };
+ return script.runInThisContext();
};
-const loadJsConfig = ({projectDir, configFile = path.join(projectDir, 'ava.config.js')}) => {
+const importConfig = async ({configFile, fileForErrorMessage}) => {
+ let module;
+ try {
+ module = await import(url.pathToFileURL(configFile)); // eslint-disable-line node/no-unsupported-features/es-syntax
+ } catch (error) {
+ throw Object.assign(new Error(`Error loading ${fileForErrorMessage}: ${error.message}`), {parent: error});
+ }
+
+ const {default: config = MISSING_DEFAULT_EXPORT} = module;
+ if (config === MISSING_DEFAULT_EXPORT) {
+ throw new Error(`${fileForErrorMessage} must have a default export`);
+ }
+
+ return config;
+};
+
+const loadJsConfig = ({projectDir, configFile = path.join(projectDir, 'ava.config.js')}, useImport = false) => {
if (!configFile.endsWith('.js')) {
return null;
}
@@ -36,7 +51,10 @@ const loadJsConfig = ({projectDir, configFile = path.join(projectDir, 'ava.confi
let config;
try {
- ({default: config = MISSING_DEFAULT_EXPORT} = evaluateJsConfig(configFile));
+ const contents = fs.readFileSync(configFile);
+ config = useImport && contents.includes('nonSemVerExperiments') && contents.includes('nextGenConfig') ?
+ importConfig({configFile, fileForErrorMessage}) :
+ evaluateJsConfig(contents, configFile) || MISSING_DEFAULT_EXPORT;
} catch (error) {
if (error.code === 'ENOENT') {
return null;
@@ -69,14 +87,17 @@ const loadCjsConfig = ({projectDir, configFile = path.join(projectDir, 'ava.conf
}
};
-const loadMjsConfig = ({projectDir, configFile = path.join(projectDir, 'ava.config.mjs')}) => {
+const loadMjsConfig = ({projectDir, configFile = path.join(projectDir, 'ava.config.mjs')}, experimentally = false) => {
if (!configFile.endsWith('.mjs')) {
return null;
}
const fileForErrorMessage = path.relative(projectDir, configFile);
try {
- fs.readFileSync(configFile);
+ const contents = fs.readFileSync(configFile);
+ if (experimentally && contents.includes('nonSemVerExperiments') && contents.includes('nextGenConfig')) {
+ return {config: importConfig({configFile, fileForErrorMessage}), fileForErrorMessage};
+ }
} catch (error) {
if (error.code === 'ENOENT') {
return null;
@@ -88,11 +109,7 @@ const loadMjsConfig = ({projectDir, configFile = path.join(projectDir, 'ava.conf
throw new Error(`AVA cannot yet load ${fileForErrorMessage} files`);
};
-function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) { // eslint-disable-line complexity
- let packageConf = pkgConf.sync('ava', {cwd: resolveFrom});
- const filepath = pkgConf.filepath(packageConf);
- const projectDir = filepath === null ? resolveFrom : path.dirname(filepath);
-
+function resolveConfigFile(projectDir, configFile) {
if (configFile) {
configFile = path.resolve(configFile); // Relative to CWD
if (path.basename(configFile) !== path.relative(projectDir, configFile)) {
@@ -104,6 +121,15 @@ function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {
}
}
+ return configFile;
+}
+
+function loadConfigSync({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) {
+ let packageConf = pkgConf.sync('ava', {cwd: resolveFrom});
+ const filepath = pkgConf.filepath(packageConf);
+ const projectDir = filepath === null ? resolveFrom : path.dirname(filepath);
+
+ configFile = resolveConfigFile(projectDir, configFile);
const allowConflictWithPackageJson = Boolean(configFile);
let [{config: fileConf, fileForErrorMessage} = {config: NO_SUCH_FILE, fileForErrorMessage: undefined}, ...conflicting] = [
@@ -163,4 +189,79 @@ function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {
return config;
}
-module.exports = loadConfig;
+exports.loadConfigSync = loadConfigSync;
+
+async function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) {
+ let packageConf = await pkgConf('ava', {cwd: resolveFrom});
+ const filepath = pkgConf.filepath(packageConf);
+ const projectDir = filepath === null ? resolveFrom : path.dirname(filepath);
+
+ configFile = resolveConfigFile(projectDir, configFile);
+ const allowConflictWithPackageJson = Boolean(configFile);
+
+ // TODO: Refactor resolution logic to implement https://github.com/avajs/ava/issues/2285.
+ let [{config: fileConf, fileForErrorMessage} = {config: NO_SUCH_FILE, fileForErrorMessage: undefined}, ...conflicting] = [
+ loadJsConfig({projectDir, configFile}, true),
+ loadCjsConfig({projectDir, configFile}),
+ loadMjsConfig({projectDir, configFile}, true)
+ ].filter(result => result !== null);
+
+ if (conflicting.length > 0) {
+ throw new Error(`Conflicting configuration in ${fileForErrorMessage} and ${conflicting.map(({fileForErrorMessage}) => fileForErrorMessage).join(' & ')}`);
+ }
+
+ let sawPromise = false;
+ if (fileConf !== NO_SUCH_FILE) {
+ if (allowConflictWithPackageJson) {
+ packageConf = {};
+ } else if (Object.keys(packageConf).length > 0) {
+ throw new Error(`Conflicting configuration in ${fileForErrorMessage} and package.json`);
+ }
+
+ if (fileConf && typeof fileConf.then === 'function') { // eslint-disable-line promise/prefer-await-to-then
+ sawPromise = true;
+ fileConf = await fileConf;
+ }
+
+ if (!isPlainObject(fileConf) && typeof fileConf !== 'function') {
+ throw new TypeError(`${fileForErrorMessage} must export a plain object or factory function`);
+ }
+
+ if (typeof fileConf === 'function') {
+ fileConf = fileConf({projectDir});
+ if (fileConf && typeof fileConf.then === 'function') { // eslint-disable-line promise/prefer-await-to-then
+ sawPromise = true;
+ fileConf = await fileConf;
+ }
+
+ if (!isPlainObject(fileConf)) {
+ throw new TypeError(`Factory method exported by ${fileForErrorMessage} must return a plain object`);
+ }
+ }
+
+ if ('ava' in fileConf) {
+ throw new Error(`Encountered ’ava’ property in ${fileForErrorMessage}; avoid wrapping the configuration`);
+ }
+ }
+
+ const config = {...defaults, nonSemVerExperiments: {}, ...fileConf, ...packageConf, projectDir};
+
+ const {nonSemVerExperiments: experiments} = config;
+ if (!isPlainObject(experiments)) {
+ throw new Error(`nonSemVerExperiments from ${fileForErrorMessage} must be an object`);
+ }
+
+ for (const key of Object.keys(experiments)) {
+ if (!EXPERIMENTS.has(key)) {
+ throw new Error(`nonSemVerExperiments.${key} from ${fileForErrorMessage} is not a supported experiment`);
+ }
+ }
+
+ if (sawPromise && experiments.nextGenConfig !== true) {
+ throw new Error(`${fileForErrorMessage} exported a promise or an asynchronous factory function. You must enable the ’asyncConfigurationLoading’ experiment for this to work.`);
+ }
+
+ return config;
+}
+
+exports.loadConfig = loadConfig;
diff --git a/lib/reporters/tap.js b/lib/reporters/tap.js
index 9757dfb84..d3d4a4603 100644
--- a/lib/reporters/tap.js
+++ b/lib/reporters/tap.js
@@ -125,12 +125,22 @@ class TapReporter {
this.reportStream.write(`# ${stripAnsi(title)}${os.EOL}`);
if (evt.logs) {
for (const log of evt.logs) {
- const logLines = indentString(log, 4).replace(/^ {4}/, ' # ');
+ const logLines = indentString(log, 4).replace(/^ {4}/gm, '# ');
this.reportStream.write(`${logLines}${os.EOL}`);
}
}
}
+ writeTimeout(evt) {
+ const err = new Error(`Exited because no new tests completed within the last ${evt.period}ms of inactivity`);
+
+ for (const [testFile, tests] of evt.pendingTests) {
+ for (const title of tests) {
+ this.writeTest({testFile, title, err}, {passed: false, todo: false, skip: false});
+ }
+ }
+ }
+
consumeStateChange(evt) { // eslint-disable-line complexity
const fileStats = this.stats && evt.testFile ? this.stats.byFile.get(evt.testFile) : null;
@@ -172,7 +182,7 @@ class TapReporter {
this.writeTest(evt, {passed: true, todo: false, skip: false});
break;
case 'timeout':
- this.writeCrash(evt, `Exited because no new tests completed within the last ${evt.period}ms of inactivity`);
+ this.writeTimeout(evt);
break;
case 'uncaught-exception':
this.writeCrash(evt);
diff --git a/lib/runner.js b/lib/runner.js
index fe240cb26..1f5577439 100644
--- a/lib/runner.js
+++ b/lib/runner.js
@@ -29,6 +29,8 @@ class Runner extends Emittery {
this.activeRunnables = new Set();
this.boundCompareTestSnapshot = this.compareTestSnapshot.bind(this);
+ this.skippedSnapshots = false;
+ this.boundSkipSnapshot = this.skipSnapshot.bind(this);
this.interrupted = false;
this.snapshots = null;
this.nextTaskIndex = 0;
@@ -199,8 +201,19 @@ class Runner extends Emittery {
return this.snapshots.compare(options);
}
+ skipSnapshot() {
+ this.skippedSnapshots = true;
+ }
+
saveSnapshotState() {
- if (this.updateSnapshots && (this.runOnlyExclusive || this.skippingTests)) {
+ if (
+ this.updateSnapshots &&
+ (
+ this.runOnlyExclusive ||
+ this.skippingTests ||
+ this.skippedSnapshots
+ )
+ ) {
return {cannotSave: true};
}
@@ -209,9 +222,11 @@ class Runner extends Emittery {
}
if (this.updateSnapshots) {
- // TODO: There may be unused snapshot files if no test caused the
- // snapshots to be loaded. Prune them. But not if tests (including hooks!)
- // were skipped. Perhaps emit a warning if this occurs?
+ return {touchedFiles: snapshotManager.cleanSnapshots({
+ file: this.file,
+ fixedLocation: this.snapshotDir,
+ projectDir: this.projectDir
+ })};
}
return {};
@@ -297,6 +312,7 @@ class Runner extends Emittery {
task.implementation :
t => task.implementation.apply(null, [t].concat(task.args)),
compareTestSnapshot: this.boundCompareTestSnapshot,
+ skipSnapshot: this.boundSkipSnapshot,
updateSnapshots: this.updateSnapshots,
metadata: {...task.metadata, associatedTaskIndex},
powerAssert: this.powerAssert,
@@ -349,6 +365,7 @@ class Runner extends Emittery {
task.implementation :
t => task.implementation.apply(null, [t].concat(task.args)),
compareTestSnapshot: this.boundCompareTestSnapshot,
+ skipSnapshot: this.boundSkipSnapshot,
updateSnapshots: this.updateSnapshots,
metadata: task.metadata,
powerAssert: this.powerAssert,
diff --git a/lib/snapshot-manager.js b/lib/snapshot-manager.js
index 119476452..5e19b1609 100644
--- a/lib/snapshot-manager.js
+++ b/lib/snapshot-manager.js
@@ -449,12 +449,49 @@ const determineSnapshotDir = mem(({file, fixedLocation, projectDir}) => {
exports.determineSnapshotDir = determineSnapshotDir;
-function load({file, fixedLocation, projectDir, recordNewSnapshots, updating}) {
+function determineSnapshotPaths({file, fixedLocation, projectDir}) {
const dir = determineSnapshotDir({file, fixedLocation, projectDir});
const relFile = path.relative(projectDir, resolveSourceFile(file));
const name = path.basename(relFile);
const reportFile = `${name}.md`;
const snapFile = `${name}.snap`;
+
+ return {
+ dir,
+ relFile,
+ snapFile,
+ reportFile
+ };
+}
+
+function cleanFile(file) {
+ try {
+ fs.unlinkSync(file);
+ return [file];
+ } catch (error) {
+ if (error.code === 'ENOENT') {
+ return [];
+ }
+
+ throw error;
+ }
+}
+
+// Remove snapshot and report if they exist. Returns an array containing the
+// paths of the touched files.
+function cleanSnapshots({file, fixedLocation, projectDir}) {
+ const {dir, snapFile, reportFile} = determineSnapshotPaths({file, fixedLocation, projectDir});
+
+ return [
+ ...cleanFile(path.join(dir, snapFile)),
+ ...cleanFile(path.join(dir, reportFile))
+ ];
+}
+
+exports.cleanSnapshots = cleanSnapshots;
+
+function load({file, fixedLocation, projectDir, recordNewSnapshots, updating}) {
+ const {dir, relFile, snapFile, reportFile} = determineSnapshotPaths({file, fixedLocation, projectDir});
const snapPath = path.join(dir, snapFile);
let appendOnly = !updating;
diff --git a/lib/test.js b/lib/test.js
index b0814654e..866590d17 100644
--- a/lib/test.js
+++ b/lib/test.js
@@ -249,6 +249,10 @@ class Test {
};
this.skipSnapshot = () => {
+ if (typeof options.skipSnapshot === 'function') {
+ options.skipSnapshot();
+ }
+
if (options.updateSnapshots) {
this.addFailedAssertion(new Error('Snapshot assertions cannot be skipped when updating snapshots'));
} else {
diff --git a/package-lock.json b/package-lock.json
index a146170de..ea2a83bb9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "ava",
- "version": "3.14.0",
+ "version": "3.15.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -107,20 +107,20 @@
}
},
"@ava/v3": {
- "version": "npm:ava@3.13.0",
- "resolved": "https://registry.npmjs.org/ava/-/ava-3.13.0.tgz",
- "integrity": "sha512-yzky+gark5PdsFFlZ4CnBVxm/OgBUWtn9vAsSSnuooVJNOk5ER17HJXVeUzy63LIt06Zy34oThcn+2ZqgMs7SA==",
+ "version": "npm:ava@3.14.0",
+ "resolved": "https://registry.npmjs.org/ava/-/ava-3.14.0.tgz",
+ "integrity": "sha512-AkXNi3DBXZE8A1z1JiNvdK6WmpN8oJQcZLkaWU24C3knCN9WVaxoDy90IVQlwjjPySeyQFqWDrsW9KomSNlRmQ==",
"dev": true,
"requires": {
"@concordance/react": "^2.0.0",
- "acorn": "^8.0.1",
+ "acorn": "^8.0.4",
"acorn-walk": "^8.0.0",
- "ansi-styles": "^4.2.1",
+ "ansi-styles": "^5.0.0",
"arrgv": "^1.0.2",
"arrify": "^2.0.1",
"callsites": "^3.1.0",
"chalk": "^4.1.0",
- "chokidar": "^3.4.2",
+ "chokidar": "^3.4.3",
"chunkd": "^2.0.1",
"ci-info": "^2.0.0",
"ci-parallel-vars": "^1.0.1",
@@ -132,9 +132,9 @@
"concordance": "^5.0.1",
"convert-source-map": "^1.7.0",
"currently-unhandled": "^0.4.1",
- "debug": "^4.2.0",
+ "debug": "^4.3.1",
"del": "^6.0.0",
- "emittery": "^0.7.1",
+ "emittery": "^0.7.2",
"equal-length": "^1.0.0",
"figures": "^3.2.0",
"globby": "^11.0.1",
@@ -147,7 +147,7 @@
"lodash": "^4.17.20",
"matcher": "^3.0.0",
"md5-hex": "^3.0.1",
- "mem": "^6.1.1",
+ "mem": "^8.0.0",
"ms": "^2.1.2",
"ora": "^5.1.0",
"p-event": "^4.2.0",
@@ -160,76 +160,66 @@
"resolve-cwd": "^3.0.0",
"slash": "^3.0.0",
"source-map-support": "^0.5.19",
- "stack-utils": "^2.0.2",
+ "stack-utils": "^2.0.3",
"strip-ansi": "^6.0.0",
"supertap": "^1.0.0",
"temp-dir": "^2.0.0",
"trim-off-newlines": "^1.0.1",
- "update-notifier": "^4.1.1",
+ "update-notifier": "^5.0.1",
"write-file-atomic": "^3.0.3",
- "yargs": "^16.0.3"
+ "yargs": "^16.2.0"
},
"dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "is-npm": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
- "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
- "mem": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz",
- "integrity": "sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==",
- "dev": true,
- "requires": {
- "map-age-cleaner": "^0.1.3",
- "mimic-fn": "^3.0.0"
- }
+ "emittery": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz",
+ "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==",
+ "dev": true
},
- "mimic-fn": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
- "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
+ "serialize-error": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
+ "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=",
"dev": true
},
- "update-notifier": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz",
- "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==",
+ "supertap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supertap/-/supertap-1.0.0.tgz",
+ "integrity": "sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA==",
"dev": true,
"requires": {
- "boxen": "^4.2.0",
- "chalk": "^3.0.0",
- "configstore": "^5.0.1",
- "has-yarn": "^2.1.0",
- "import-lazy": "^2.1.0",
- "is-ci": "^2.0.0",
- "is-installed-globally": "^0.3.1",
- "is-npm": "^4.0.0",
- "is-yarn-global": "^0.3.0",
- "latest-version": "^5.0.0",
- "pupa": "^2.0.1",
- "semver-diff": "^3.1.1",
- "xdg-basedir": "^4.0.0"
+ "arrify": "^1.0.1",
+ "indent-string": "^3.2.0",
+ "js-yaml": "^3.10.0",
+ "serialize-error": "^2.1.0",
+ "strip-ansi": "^4.0.0"
},
"dependencies": {
- "chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "ansi-regex": "^3.0.0"
}
}
}
@@ -237,33 +227,32 @@
}
},
"@babel/code-frame": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
- "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+ "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
"requires": {
"@babel/highlight": "^7.10.4"
}
},
"@babel/core": {
- "version": "7.12.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz",
- "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==",
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz",
+ "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.10.4",
- "@babel/generator": "^7.12.5",
+ "@babel/generator": "^7.12.10",
"@babel/helper-module-transforms": "^7.12.1",
"@babel/helpers": "^7.12.5",
- "@babel/parser": "^7.12.7",
+ "@babel/parser": "^7.12.10",
"@babel/template": "^7.12.7",
- "@babel/traverse": "^7.12.9",
- "@babel/types": "^7.12.7",
+ "@babel/traverse": "^7.12.10",
+ "@babel/types": "^7.12.10",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.1",
"json5": "^2.1.2",
"lodash": "^4.17.19",
- "resolve": "^1.3.2",
"semver": "^5.4.1",
"source-map": "^0.5.0"
},
@@ -283,12 +272,12 @@
}
},
"@babel/generator": {
- "version": "7.12.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz",
- "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==",
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz",
+ "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.5",
+ "@babel/types": "^7.12.11",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
},
@@ -302,23 +291,23 @@
}
},
"@babel/helper-function-name": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
- "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz",
+ "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.10.4",
- "@babel/template": "^7.10.4",
- "@babel/types": "^7.10.4"
+ "@babel/helper-get-function-arity": "^7.12.10",
+ "@babel/template": "^7.12.7",
+ "@babel/types": "^7.12.11"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
- "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz",
+ "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.4"
+ "@babel/types": "^7.12.10"
}
},
"@babel/helper-member-expression-to-functions": {
@@ -357,12 +346,12 @@
}
},
"@babel/helper-optimise-call-expression": {
- "version": "7.12.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.7.tgz",
- "integrity": "sha512-I5xc9oSJ2h59OwyUqjv95HRyzxj53DAubUERgQMrpcCEYQyToeHA+NEcUEsVWB4j53RDeskeBJ0SgRAYHDBckw==",
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz",
+ "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.7"
+ "@babel/types": "^7.12.10"
}
},
"@babel/helper-plugin-utils": {
@@ -372,15 +361,15 @@
"dev": true
},
"@babel/helper-replace-supers": {
- "version": "7.12.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz",
- "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==",
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz",
+ "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==",
"dev": true,
"requires": {
- "@babel/helper-member-expression-to-functions": "^7.12.1",
- "@babel/helper-optimise-call-expression": "^7.10.4",
- "@babel/traverse": "^7.12.5",
- "@babel/types": "^7.12.5"
+ "@babel/helper-member-expression-to-functions": "^7.12.7",
+ "@babel/helper-optimise-call-expression": "^7.12.10",
+ "@babel/traverse": "^7.12.10",
+ "@babel/types": "^7.12.11"
}
},
"@babel/helper-simple-access": {
@@ -402,18 +391,18 @@
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.11.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
- "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz",
+ "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==",
"dev": true,
"requires": {
- "@babel/types": "^7.11.0"
+ "@babel/types": "^7.12.11"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
- "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw=="
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+ "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
},
"@babel/helpers": {
"version": "7.12.5",
@@ -483,9 +472,9 @@
}
},
"@babel/parser": {
- "version": "7.12.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz",
- "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==",
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz",
+ "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==",
"dev": true
},
"@babel/plugin-proposal-do-expressions": {
@@ -589,29 +578,29 @@
}
},
"@babel/traverse": {
- "version": "7.12.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz",
- "integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==",
+ "version": "7.12.12",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz",
+ "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.10.4",
- "@babel/generator": "^7.12.5",
- "@babel/helper-function-name": "^7.10.4",
- "@babel/helper-split-export-declaration": "^7.11.0",
- "@babel/parser": "^7.12.7",
- "@babel/types": "^7.12.7",
+ "@babel/code-frame": "^7.12.11",
+ "@babel/generator": "^7.12.11",
+ "@babel/helper-function-name": "^7.12.11",
+ "@babel/helper-split-export-declaration": "^7.12.11",
+ "@babel/parser": "^7.12.11",
+ "@babel/types": "^7.12.12",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.19"
}
},
"@babel/types": {
- "version": "7.12.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz",
- "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==",
+ "version": "7.12.12",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz",
+ "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.10.4",
+ "@babel/helper-validator-identifier": "^7.12.11",
"lodash": "^4.17.19",
"to-fast-properties": "^2.0.0"
}
@@ -701,25 +690,25 @@
}
},
"@nodelib/fs.scandir": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
- "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
+ "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
"requires": {
- "@nodelib/fs.stat": "2.0.3",
+ "@nodelib/fs.stat": "2.0.4",
"run-parallel": "^1.1.9"
}
},
"@nodelib/fs.stat": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
- "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA=="
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
+ "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q=="
},
"@nodelib/fs.walk": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
- "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
+ "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
"requires": {
- "@nodelib/fs.scandir": "2.1.3",
+ "@nodelib/fs.scandir": "2.1.4",
"fastq": "^1.6.0"
}
},
@@ -828,9 +817,9 @@
"dev": true
},
"@types/node": {
- "version": "14.14.10",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
- "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==",
+ "version": "14.14.17",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.17.tgz",
+ "integrity": "sha512-G0lD1/7qD60TJ/mZmhog76k7NcpLWkPVGgzkRy3CTlnFu4LUQh5v2Wa661z6vnXmD8EQrnALUyf0VRtrACYztw==",
"dev": true
},
"@types/normalize-package-data": {
@@ -845,13 +834,13 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.9.0.tgz",
- "integrity": "sha512-WrVzGMzzCrgrpnQMQm4Tnf+dk+wdl/YbgIgd5hKGa2P+lnJ2MON+nQnbwgbxtN9QDLi8HO+JAq0/krMnjQK6Cw==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.11.1.tgz",
+ "integrity": "sha512-fABclAX2QIEDmTMk6Yd7Muv1CzFLwWM4505nETzRHpP3br6jfahD9UUJkhnJ/g2m7lwfz8IlswcwGGPGiq9exw==",
"dev": true,
"requires": {
- "@typescript-eslint/experimental-utils": "4.9.0",
- "@typescript-eslint/scope-manager": "4.9.0",
+ "@typescript-eslint/experimental-utils": "4.11.1",
+ "@typescript-eslint/scope-manager": "4.11.1",
"debug": "^4.1.1",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^3.0.0",
@@ -860,55 +849,55 @@
}
},
"@typescript-eslint/experimental-utils": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.9.0.tgz",
- "integrity": "sha512-0p8GnDWB3R2oGhmRXlEnCvYOtaBCijtA5uBfH5GxQKsukdSQyI4opC4NGTUb88CagsoNQ4rb/hId2JuMbzWKFQ==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.11.1.tgz",
+ "integrity": "sha512-mAlWowT4A6h0TC9F+J5pdbEhjNiEMO+kqPKQ4sc3fVieKL71dEqfkKgtcFVSX3cjSBwYwhImaQ/mXQF0oaI38g==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
- "@typescript-eslint/scope-manager": "4.9.0",
- "@typescript-eslint/types": "4.9.0",
- "@typescript-eslint/typescript-estree": "4.9.0",
+ "@typescript-eslint/scope-manager": "4.11.1",
+ "@typescript-eslint/types": "4.11.1",
+ "@typescript-eslint/typescript-estree": "4.11.1",
"eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0"
}
},
"@typescript-eslint/parser": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.9.0.tgz",
- "integrity": "sha512-QRSDAV8tGZoQye/ogp28ypb8qpsZPV6FOLD+tbN4ohKUWHD2n/u0Q2tIBnCsGwQCiD94RdtLkcqpdK4vKcLCCw==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.11.1.tgz",
+ "integrity": "sha512-BJ3jwPQu1jeynJ5BrjLuGfK/UJu6uwHxJ/di7sanqmUmxzmyIcd3vz58PMR7wpi8k3iWq2Q11KMYgZbUpRoIPw==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "4.9.0",
- "@typescript-eslint/types": "4.9.0",
- "@typescript-eslint/typescript-estree": "4.9.0",
+ "@typescript-eslint/scope-manager": "4.11.1",
+ "@typescript-eslint/types": "4.11.1",
+ "@typescript-eslint/typescript-estree": "4.11.1",
"debug": "^4.1.1"
}
},
"@typescript-eslint/scope-manager": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.9.0.tgz",
- "integrity": "sha512-q/81jtmcDtMRE+nfFt5pWqO0R41k46gpVLnuefqVOXl4QV1GdQoBWfk5REcipoJNQH9+F5l+dwa9Li5fbALjzg==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.11.1.tgz",
+ "integrity": "sha512-Al2P394dx+kXCl61fhrrZ1FTI7qsRDIUiVSuN6rTwss6lUn8uVO2+nnF4AvO0ug8vMsy3ShkbxLu/uWZdTtJMQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.9.0",
- "@typescript-eslint/visitor-keys": "4.9.0"
+ "@typescript-eslint/types": "4.11.1",
+ "@typescript-eslint/visitor-keys": "4.11.1"
}
},
"@typescript-eslint/types": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.9.0.tgz",
- "integrity": "sha512-luzLKmowfiM/IoJL/rus1K9iZpSJK6GlOS/1ezKplb7MkORt2dDcfi8g9B0bsF6JoRGhqn0D3Va55b+vredFHA==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.11.1.tgz",
+ "integrity": "sha512-5kvd38wZpqGY4yP/6W3qhYX6Hz0NwUbijVsX2rxczpY6OXaMxh0+5E5uLJKVFwaBM7PJe1wnMym85NfKYIh6CA==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.9.0.tgz",
- "integrity": "sha512-rmDR++PGrIyQzAtt3pPcmKWLr7MA+u/Cmq9b/rON3//t5WofNR4m/Ybft2vOLj0WtUzjn018ekHjTsnIyBsQug==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.1.tgz",
+ "integrity": "sha512-tC7MKZIMRTYxQhrVAFoJq/DlRwv1bnqA4/S2r3+HuHibqvbrPcyf858lNzU7bFmy4mLeIHFYr34ar/1KumwyRw==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.9.0",
- "@typescript-eslint/visitor-keys": "4.9.0",
+ "@typescript-eslint/types": "4.11.1",
+ "@typescript-eslint/visitor-keys": "4.11.1",
"debug": "^4.1.1",
"globby": "^11.0.1",
"is-glob": "^4.0.1",
@@ -918,12 +907,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.9.0.tgz",
- "integrity": "sha512-sV45zfdRqQo1A97pOSx3fsjR+3blmwtdCt8LDrXgCX36v4Vmz4KHrhpV6Fo2cRdXmyumxx11AHw0pNJqCNpDyg==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.1.tgz",
+ "integrity": "sha512-IrlBhD9bm4bdYcS8xpWarazkKXlE7iYb1HzRuyBP114mIaj5DJPo11Us1HgH60dTt41TCZXMaTCAW+OILIYPOg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.9.0",
+ "@typescript-eslint/types": "4.11.1",
"eslint-visitor-keys": "^2.0.0"
}
},
@@ -1429,8 +1418,7 @@
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "dev": true
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
@@ -1452,6 +1440,16 @@
"integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==",
"dev": true
},
+ "bl": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
+ "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
"blueimp-md5": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.18.0.tgz",
@@ -1595,17 +1593,6 @@
"safe-buffer": "^5.2.0"
},
"dependencies": {
- "readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1630,22 +1617,12 @@
"dev": true
},
"buffer": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
- "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
- "dev": true,
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
- "base64-js": "^1.0.2",
- "ieee754": "^1.1.4",
- "isarray": "^1.0.0"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- }
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
}
},
"buffer-from": {
@@ -1666,9 +1643,9 @@
"dev": true
},
"c8": {
- "version": "7.3.5",
- "resolved": "https://registry.npmjs.org/c8/-/c8-7.3.5.tgz",
- "integrity": "sha512-VNiZoxnInBJLW8uUuyLkiqMKWh1OAsYS+DjWsMhvcrfGPrVx3vwqD9627/7ZhFSF86MCBINDi+PD6Midw0KHRg==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-7.4.0.tgz",
+ "integrity": "sha512-K8I7MEe2i4L91YBX3HtV10kKpU5uqGeyjtsdGS2FxfT0pk15d9jthujjR1ORRLrCJ4tXuDK9PSH2vChzRDoAZw==",
"dev": true,
"requires": {
"@bcoe/v8-coverage": "^0.2.3",
@@ -1681,7 +1658,7 @@
"istanbul-reports": "^3.0.2",
"rimraf": "^3.0.0",
"test-exclude": "^6.0.0",
- "v8-to-istanbul": "^7.0.0",
+ "v8-to-istanbul": "^7.1.0",
"yargs": "^16.0.0",
"yargs-parser": "^20.0.0"
},
@@ -2400,6 +2377,13 @@
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"requires": {
"ms": "2.1.2"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
}
},
"decamelize": {
@@ -2684,9 +2668,9 @@
}
},
"emittery": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz",
- "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ=="
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.0.tgz",
+ "integrity": "sha512-XMGToId3CejfmZg/0qOzdTT3WFuAN8fQYtcKXccabRfCzGiWMSTydMshHGLyx9C/ejMl4nw9tvqrn12QVFPIUg=="
},
"emoji-regex": {
"version": "8.0.0",
@@ -2811,9 +2795,9 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": {
- "version": "7.15.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz",
- "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==",
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.16.0.tgz",
+ "integrity": "sha512-iVWPS785RuDA4dWuhhgXTNrGxHHK3a8HLSMBgbbU59ruJDubUraXN8N5rn7kb8tG6sjg74eE0RA3YWT51eusEw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@@ -2850,7 +2834,7 @@
"semver": "^7.2.1",
"strip-ansi": "^6.0.0",
"strip-json-comments": "^3.1.0",
- "table": "^5.2.3",
+ "table": "^6.0.4",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
},
@@ -2895,21 +2879,10 @@
}
},
"eslint-config-prettier": {
- "version": "6.15.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz",
- "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==",
- "dev": true,
- "requires": {
- "get-stdin": "^6.0.0"
- },
- "dependencies": {
- "get-stdin": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
- "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
- "dev": true
- }
- }
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz",
+ "integrity": "sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA==",
+ "dev": true
},
"eslint-config-xo": {
"version": "0.33.1",
@@ -3334,9 +3307,9 @@
}
},
"eslint-plugin-prettier": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.2.0.tgz",
- "integrity": "sha512-kOUSJnFjAUFKwVxuzy6sA5yyMx6+o9ino4gCdShzBNx4eyFRudWRYKCFolKjoM40PEiuU6Cn7wBLfq3WsGg7qg==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.0.tgz",
+ "integrity": "sha512-tMTwO8iUWlSRZIwS9k7/E4vrTsfvsrcM5p1eftyuqWH25nKsz/o6/54I7jwQ/3zobISyC7wMy9ZsFwgTxOcOpQ==",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0"
@@ -3389,9 +3362,9 @@
}
},
"eslint-rule-docs": {
- "version": "1.1.216",
- "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.216.tgz",
- "integrity": "sha512-+Gs6G41O/A/aBj3JJWI2CwFZZ5XxkOPdlz2NRGujEqfYtAnZIIQHdVn7mw6wIZ0nGefLXpBqAekJkW8LbSsqvg==",
+ "version": "1.1.217",
+ "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.217.tgz",
+ "integrity": "sha512-xqd9Dtrr0bwoMtcQniZ+V/oXmixPe8TbPcKbMy4tzKIljUhiUpQDYrDZ6H3fIqUBlCcl9r7UhLoERqsMA74bcg==",
"dev": true
},
"eslint-scope": {
@@ -3405,23 +3378,15 @@
}
},
"eslint-template-visitor": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.1.tgz",
- "integrity": "sha512-q3SxoBXz0XjPGkUpwGVAwIwIPIxzCAJX1uwfVc8tW3v7u/zS7WXNH3I2Mu2MDz2NgSITAyKLRaQFPHu/iyKxDQ==",
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.2.tgz",
+ "integrity": "sha512-SkcLjzKw3JjKTWHacRDeLBa2gxb600zbCKTkXj/V97QnZ9yxkknoPL8vc8PFueqbFXP7mYNTQzjCjcMpTRdRaA==",
"dev": true,
"requires": {
"babel-eslint": "^10.1.0",
- "eslint-visitor-keys": "^1.3.0",
+ "eslint-visitor-keys": "^2.0.0",
"esquery": "^1.3.1",
"multimap": "^1.1.0"
- },
- "dependencies": {
- "eslint-visitor-keys": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
- "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
- "dev": true
- }
}
},
"eslint-utils": {
@@ -3790,9 +3755,9 @@
"dev": true
},
"fastq": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz",
- "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz",
+ "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==",
"requires": {
"reusify": "^1.0.4"
}
@@ -3942,18 +3907,18 @@
"dev": true
},
"flow-parser": {
- "version": "0.138.0",
- "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.138.0.tgz",
- "integrity": "sha512-LFnTyjrv39UvCWl8NOcpByr/amj8a5k5z7isO2wv4T43nNrUnHQwX3rarTz9zcpHXkDAQv6X4MfQ4ZzJUptpbw==",
+ "version": "0.141.0",
+ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.141.0.tgz",
+ "integrity": "sha512-WKdBiR9sDfkgEyPGhIgldUrVM08D57CgHLgd0FOXbhcVYXNfw+eHSApQ8SdcdQQoqrOvhlcVRB8lsn9bD5GQOw==",
"dev": true
},
"flow-remove-types": {
- "version": "2.138.0",
- "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.138.0.tgz",
- "integrity": "sha512-gWZYpCAcpX5SD7j1S5DrWLWm+ir5LXkkRTrCokTdO5aW6M1cqQmHN5lxwoQTqkP8PfgXI8ILD810TL9CvexpgA==",
+ "version": "2.141.0",
+ "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.141.0.tgz",
+ "integrity": "sha512-N5t55GrD3VgzgwWSOja6IULbz/W1HkmPKwwic+zsYhpW1UfLBwsO4y0j+P5J+wr0a/xdm2rH1dBLpKiRPQDBIw==",
"dev": true,
"requires": {
- "flow-parser": "^0.138.0",
+ "flow-parser": "^0.141.0",
"pirates": "^3.0.2",
"vlq": "^0.2.1"
}
@@ -4068,9 +4033,9 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"get-intrinsic": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
- "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz",
+ "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==",
"dev": true,
"requires": {
"function-bind": "^1.1.1",
@@ -4139,11 +4104,11 @@
"dev": true
},
"global-dirs": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
- "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
+ "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==",
"requires": {
- "ini": "^1.3.5"
+ "ini": "1.3.7"
}
},
"globals": {
@@ -4307,17 +4272,6 @@
"safe-buffer": "^5.2.0"
},
"dependencies": {
- "readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -4407,8 +4361,7 @@
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "dev": true
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"ignore": {
"version": "5.1.8",
@@ -4421,9 +4374,9 @@
"integrity": "sha512-+mQSgMRiFD3L3AOxLYOCxjIq4OnAmo5CIuC+lj5ehCJcPtV++QacEV7FdpzvYxH6DaOySWzQU6RR0lPLy37ckA=="
},
"import-fresh": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
- "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
@@ -4453,9 +4406,9 @@
}
},
"import-modules": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.0.0.tgz",
- "integrity": "sha512-iczM/v9drffdNnABOKwj0f9G3cFDon99VcG1mxeBsdqnbd+vnQ5c2uAiCHNQITqFTOPaEvwg3VjoWCur0uHLEw==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz",
+ "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==",
"dev": true
},
"imurmurhash": {
@@ -4483,9 +4436,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
- "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
+ "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ=="
},
"interpret": {
"version": "1.4.0",
@@ -5183,9 +5136,9 @@
"dev": true
},
"js-yaml": {
- "version": "3.14.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
- "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -5801,9 +5754,9 @@
"dev": true
},
"ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"multimap": {
"version": "1.1.0",
@@ -5811,11 +5764,6 @@
"integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==",
"dev": true
},
- "mute-stream": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
- "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
- },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -5897,11 +5845,54 @@
"vm-browserify": "^1.0.1"
},
"dependencies": {
+ "buffer": {
+ "version": "4.9.2",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+ "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4",
+ "isarray": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
"dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
}
}
},
@@ -6471,16 +6462,16 @@
}
},
"ora": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/ora/-/ora-5.1.0.tgz",
- "integrity": "sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.2.0.tgz",
+ "integrity": "sha512-+wG2v8TUU8EgzPHun1k/n45pXquQ9fHnbXVetl9rRgO6kjZszGGbraF3XPTIdgeA+s1lbRjSEftAnyT0w8ZMvQ==",
"requires": {
+ "bl": "^4.0.3",
"chalk": "^4.1.0",
"cli-cursor": "^3.1.0",
- "cli-spinners": "^2.4.0",
+ "cli-spinners": "^2.5.0",
"is-interactive": "^1.0.0",
"log-symbols": "^4.0.0",
- "mute-stream": "0.0.8",
"strip-ansi": "^6.0.0",
"wcwidth": "^1.0.1"
}
@@ -7144,35 +7135,13 @@
}
},
"readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
}
},
"readdirp": {
@@ -7457,9 +7426,19 @@
}
},
"serialize-error": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
- "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go="
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "requires": {
+ "type-fest": "^0.13.1"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="
+ }
+ }
},
"set-blocking": {
"version": "2.0.0",
@@ -7536,15 +7515,15 @@
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"sinon": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz",
- "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==",
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.2.tgz",
+ "integrity": "sha512-9Owi+RisvCZpB0bdOVFfL314I6I4YoRlz6Isi4+fr8q8YQsDPoCe5UnmNtKHRThX3negz2bXHWIuiPa42vM8EQ==",
"dev": true,
"requires": {
"@sinonjs/commons": "^1.8.1",
"@sinonjs/fake-timers": "^6.0.1",
"@sinonjs/formatio": "^5.0.1",
- "@sinonjs/samsam": "^5.2.0",
+ "@sinonjs/samsam": "^5.3.0",
"diff": "^4.0.2",
"nise": "^4.0.4",
"supports-color": "^7.1.0"
@@ -7915,6 +7894,38 @@
"requires": {
"inherits": "~2.0.1",
"readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
}
},
"stream-http": {
@@ -7928,6 +7939,38 @@
"readable-stream": "^2.3.6",
"to-arraybuffer": "^1.0.0",
"xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
}
},
"string-width": {
@@ -7964,7 +8007,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "dev": true,
"requires": {
"safe-buffer": "~5.2.0"
},
@@ -7972,8 +8014,7 @@
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
}
}
},
@@ -8020,40 +8061,15 @@
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
"supertap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supertap/-/supertap-1.0.0.tgz",
- "integrity": "sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supertap/-/supertap-2.0.0.tgz",
+ "integrity": "sha512-jRzcXlCeDYvKoZGA5oRhYyR3jUIYu0enkSxtmAgHRlD7HwrovTpH4bDSi0py9FtuA8si9cW/fKommJHuaoDHJA==",
"requires": {
- "arrify": "^1.0.1",
- "indent-string": "^3.2.0",
- "js-yaml": "^3.10.0",
- "serialize-error": "^2.1.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
- },
- "arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
- },
- "indent-string": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
- "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok="
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
+ "arrify": "^2.0.1",
+ "indent-string": "^4.0.0",
+ "js-yaml": "^3.14.0",
+ "serialize-error": "^7.0.1",
+ "strip-ansi": "^6.0.0"
}
},
"supports-color": {
@@ -8075,94 +8091,35 @@
}
},
"table": {
- "version": "5.4.6",
- "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
- "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.0.4.tgz",
+ "integrity": "sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw==",
"dev": true,
"requires": {
- "ajv": "^6.10.2",
- "lodash": "^4.17.14",
- "slice-ansi": "^2.1.0",
- "string-width": "^3.0.0"
+ "ajv": "^6.12.4",
+ "lodash": "^4.17.20",
+ "slice-ansi": "^4.0.0",
+ "string-width": "^4.2.0"
},
"dependencies": {
- "ansi-regex": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
- "dev": true
- },
"ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "astral-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
- "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
- "dev": true
- },
- "color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
- "color-name": "1.1.3"
+ "color-convert": "^2.0.1"
}
},
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
- },
- "emoji-regex": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
- "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
"slice-ansi": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
- "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.0",
- "astral-regex": "^1.0.0",
- "is-fullwidth-code-point": "^2.0.0"
- }
- },
- "string-width": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
- "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
- "dev": true,
- "requires": {
- "emoji-regex": "^7.0.1",
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^5.1.0"
- }
- },
- "strip-ansi": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
- "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
"dev": true,
"requires": {
- "ansi-regex": "^4.1.0"
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
}
}
}
@@ -9837,9 +9794,9 @@
}
},
"typescript": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz",
- "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
+ "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
"dev": true
},
"unc-path-regex": {
@@ -10035,8 +9992,7 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.4.0",
@@ -10051,9 +10007,9 @@
"dev": true
},
"v8-to-istanbul": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.0.0.tgz",
- "integrity": "sha512-fLL2rFuQpMtm9r8hrAV2apXX/WqHJ6+IC4/eQVdMDGBUgH/YMV4Gv3duk3kjmyg6uiQWBAA9nJwue4iJUOkHeA==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz",
+ "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.1",
@@ -10185,18 +10141,18 @@
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q=="
},
"xo": {
- "version": "0.35.0",
- "resolved": "https://registry.npmjs.org/xo/-/xo-0.35.0.tgz",
- "integrity": "sha512-0k9m8pHilTzAYqw3L7qEXxuo3X87M2pYDBSzLvFD5aIpXEydZvSHLR7xbGrXKpK+sWGi825lL7+iEC1s/XZCRQ==",
+ "version": "0.36.1",
+ "resolved": "https://registry.npmjs.org/xo/-/xo-0.36.1.tgz",
+ "integrity": "sha512-Y4ZlBipRa9BYZDzGUV8PbCVgdP0qD5HfbM2x6Ilp8NKkdQMQXD2OyeJL0hyeAyXe+9X25VZSfeHBmSDi/DHXFA==",
"dev": true,
"requires": {
- "@typescript-eslint/eslint-plugin": "^4.8.1",
- "@typescript-eslint/parser": "^4.8.1",
+ "@typescript-eslint/eslint-plugin": "^4.9.1",
+ "@typescript-eslint/parser": "^4.9.1",
"arrify": "^2.0.1",
"cosmiconfig": "^7.0.0",
"debug": "^4.3.1",
- "eslint": "^7.13.0",
- "eslint-config-prettier": "^6.15.0",
+ "eslint": "^7.15.0",
+ "eslint-config-prettier": "^7.0.0",
"eslint-config-xo": "^0.33.1",
"eslint-config-xo-typescript": "^0.36.0",
"eslint-formatter-pretty": "^4.0.0",
@@ -10206,14 +10162,14 @@
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-no-use-extend-native": "^0.5.0",
"eslint-plugin-node": "^11.1.0",
- "eslint-plugin-prettier": "^3.1.4",
+ "eslint-plugin-prettier": "^3.2.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-unicorn": "^23.0.0",
"find-cache-dir": "^3.3.1",
"find-up": "^5.0.0",
"fs-extra": "^9.0.1",
"get-stdin": "^8.0.0",
- "globby": "^9.0.0",
+ "globby": "^9.2.0",
"has-flag": "^4.0.0",
"imurmurhash": "^0.1.4",
"is-path-inside": "^3.0.2",
@@ -10225,10 +10181,10 @@
"open-editor": "^2.0.1",
"p-reduce": "^2.1.0",
"path-exists": "^4.0.0",
- "prettier": "^2.1.2",
+ "prettier": "^2.2.1",
"resolve-cwd": "^3.0.0",
"resolve-from": "^5.0.0",
- "semver": "^7.3.2",
+ "semver": "^7.3.4",
"slash": "^3.0.0",
"to-absolute-glob": "^2.0.2",
"typescript": "^4.1.2",
@@ -10459,9 +10415,9 @@
}
},
"meow": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-8.0.0.tgz",
- "integrity": "sha512-nbsTRz2fwniJBFgUkcdISq8y/q9n9VbiHYbfwklFh5V4V2uAcxtKQkDc0yCLPM/kP0d+inZBewn3zJqewHE7kg==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.0.tgz",
+ "integrity": "sha512-fNWkgM1UVMey2kf24yLiccxLihc5W+6zVus3/N0b+VfnJgxV99E9u04X6NAiKdg6ED7DAQBX5sy36NM0QJZkWA==",
"dev": true,
"requires": {
"@types/minimist": "^1.2.0",
diff --git a/package.json b/package.json
index 13b0f417a..1bc229c7c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ava",
- "version": "3.14.0",
+ "version": "3.15.0",
"description": "Node.js test runner that lets you develop with confidence.",
"license": "MIT",
"repository": "avajs/ava",
@@ -10,7 +10,8 @@
"node": ">=10.18.0 <11 || >=12.14.0 <12.17.0 || >=12.17.0 <13 || >=14.0.0 <15 || >=15"
},
"scripts": {
- "test": "xo && tsd && c8 --report=none tap && c8 --report=none --no-clean test-ava && c8 report"
+ "cover": "c8 --report=none tap && c8 --report=none --no-clean test-ava && c8 report",
+ "test": "xo && tsd && npm run -s cover"
},
"files": [
"lib",
@@ -78,7 +79,7 @@
"currently-unhandled": "^0.4.1",
"debug": "^4.3.1",
"del": "^6.0.0",
- "emittery": "^0.7.2",
+ "emittery": "^0.8.0",
"equal-length": "^1.0.0",
"figures": "^3.2.0",
"globby": "^11.0.1",
@@ -92,8 +93,8 @@
"matcher": "^3.0.0",
"md5-hex": "^3.0.1",
"mem": "^8.0.0",
- "ms": "^2.1.2",
- "ora": "^5.1.0",
+ "ms": "^2.1.3",
+ "ora": "^5.2.0",
"p-event": "^4.2.0",
"p-map": "^4.0.0",
"picomatch": "^2.2.2",
@@ -106,7 +107,7 @@
"source-map-support": "^0.5.19",
"stack-utils": "^2.0.3",
"strip-ansi": "^6.0.0",
- "supertap": "^1.0.0",
+ "supertap": "^2.0.0",
"temp-dir": "^2.0.0",
"trim-off-newlines": "^1.0.1",
"update-notifier": "^5.0.1",
@@ -119,25 +120,26 @@
"@babel/plugin-proposal-do-expressions": "^7.12.1",
"@sinonjs/fake-timers": "^6.0.1",
"ansi-escapes": "^4.3.1",
- "c8": "^7.3.5",
+ "c8": "^7.4.0",
"delay": "^4.4.0",
"esm": "^3.2.25",
"execa": "^5.0.0",
+ "fs-extra": "^9.0.1",
"get-stream": "^6.0.0",
"it-first": "^1.0.4",
"proxyquire": "^2.1.3",
"react": "^16.14.0",
"react-test-renderer": "^16.14.0",
"replace-string": "^3.1.0",
- "sinon": "^9.2.1",
+ "sinon": "^9.2.2",
"source-map-fixtures": "^2.1.0",
"tap": "^14.11.0",
"temp-write": "^4.0.0",
"tempy": "^1.0.0",
"touch": "^3.1.0",
"tsd": "^0.14.0",
- "typescript": "^4.1.2",
- "xo": "^0.35.0",
+ "typescript": "^4.1.3",
+ "xo": "^0.36.1",
"zen-observable": "^0.8.15"
}
}
diff --git a/readme.md b/readme.md
index 9f619ac1d..e2a8f75d2 100644
--- a/readme.md
+++ b/readme.md
@@ -1,8 +1,5 @@
#
-[](https://travis-ci.org/avajs/ava) [](https://codecov.io/gh/avajs/ava/branch/master) [](https://github.com/xojs/xo) [](https://spectrum.chat/ava)
-[](https://github.com/sindresorhus/awesome-nodejs)
-
AVA is a test runner for Node.js with a concise API, detailed error output, embrace of new language features and process isolation that lets you develop with confidence 🚀
Follow the [AVA Twitter account](https://twitter.com/ava__js) for updates.
@@ -188,9 +185,7 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
## Support
-- [Stack Overflow](https://stackoverflow.com/questions/tagged/ava)
-- [Spectrum](https://spectrum.chat/ava)
-- [Twitter](https://twitter.com/ava__js)
+- [GitHub Discussions](https://github.com/avajs/ava/discussions)
## Related
diff --git a/test-tap/fixture/snapshots/watcher-rerun-unlink/package.json b/test-tap/fixture/snapshots/watcher-rerun-unlink/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test-tap/fixture/snapshots/watcher-rerun-unlink/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test-tap/fixture/snapshots/watcher-rerun-unlink/test.js b/test-tap/fixture/snapshots/watcher-rerun-unlink/test.js
new file mode 100644
index 000000000..885f9e698
--- /dev/null
+++ b/test-tap/fixture/snapshots/watcher-rerun-unlink/test.js
@@ -0,0 +1,21 @@
+const test = require('../../../..');
+
+if (process.env.TEMPLATE) {
+ test('test title', t => {
+ t.snapshot({foo: 'bar'});
+ t.snapshot({answer: 42});
+ t.pass();
+ });
+
+ test('another test', t => {
+ t.snapshot(new Map());
+ });
+} else {
+ test('test title', t => {
+ t.pass();
+ });
+
+ test('another test', t => {
+ t.pass();
+ });
+}
diff --git a/test-tap/integration/watcher.js b/test-tap/integration/watcher.js
index e30896f4c..1cf6cdf85 100644
--- a/test-tap/integration/watcher.js
+++ b/test-tap/integration/watcher.js
@@ -82,6 +82,52 @@ test('watcher does not rerun test files when they write snapshot files', t => {
});
});
+test('watcher does not rerun test files when they unlink snapshot files', t => {
+ // Run fixture as template to generate snapshots
+ execCli(
+ ['--update-snapshots'],
+ {
+ dirname: 'fixture/snapshots/watcher-rerun-unlink',
+ env: {AVA_FORCE_CI: 'not-ci', TEMPLATE: 'true'}
+ },
+ err => {
+ t.ifError(err);
+
+ // Run fixture in watch mode; snapshots should be removed, and watcher should not rerun
+ let killed = false;
+
+ const child = execCli(
+ ['--verbose', '--watch', '--update-snapshots', 'test.js'],
+ {
+ dirname: 'fixture/snapshots/watcher-rerun-unlink',
+ env: {AVA_FORCE_CI: 'not-ci'}
+ },
+ err => {
+ t.ok(killed);
+ t.ifError(err);
+ t.end();
+ }
+ );
+
+ let buffer = '';
+ let passedFirst = false;
+ child.stdout.on('data', string => {
+ buffer += string;
+ if (buffer.includes('2 tests passed') && !passedFirst) {
+ buffer = '';
+ passedFirst = true;
+ setTimeout(() => {
+ child.kill();
+ killed = true;
+ }, 500);
+ } else if (passedFirst && !killed) {
+ t.is(buffer.replace(/\s/g, '').replace(END_MESSAGE.replace(/\s/g, ''), ''), '');
+ }
+ });
+ }
+ );
+});
+
test('watcher does not rerun test files when ignored files change', t => {
let killed = false;
diff --git a/test-tap/load-config.js b/test-tap/load-config.js
index bfa48d064..0d1f21873 100644
--- a/test-tap/load-config.js
+++ b/test-tap/load-config.js
@@ -1,7 +1,7 @@
'use strict';
const path = require('path');
const tap = require('tap');
-const loadConfig = require('../lib/load-config');
+const {loadConfigSync} = require('../lib/load-config');
const {test} = tap;
@@ -16,40 +16,40 @@ const changeDir = fixtureDir => {
test('finds config in package.json', t => {
changeDir('package-only');
- const conf = loadConfig();
+ const conf = loadConfigSync();
t.is(conf.failFast, true);
t.end();
});
test('loads config from a particular directory', t => {
changeDir('throws');
- const conf = loadConfig({resolveFrom: path.resolve(__dirname, 'fixture', 'load-config', 'package-only')});
+ const conf = loadConfigSync({resolveFrom: path.resolve(__dirname, 'fixture', 'load-config', 'package-only')});
t.is(conf.failFast, true);
t.end();
});
test('throws an error if both configs are present', t => {
changeDir('package-yes-file-yes');
- t.throws(loadConfig, /Conflicting configuration in ava.config.js and package.json/);
+ t.throws(loadConfigSync, /Conflicting configuration in ava.config.js and package.json/);
t.end();
});
test('explicit configFile option overrides package.json config', t => {
changeDir('package-yes-explicit-yes');
- const {files} = loadConfig({configFile: 'explicit.js'});
+ const {files} = loadConfigSync({configFile: 'explicit.js'});
t.is(files, 'package-yes-explicit-yes-test-value');
t.end();
});
test('throws if configFile option is not in the same directory as the package.json file', t => {
changeDir('package-yes-explicit-yes');
- t.throws(() => loadConfig({configFile: 'nested/explicit.js'}), /Config files must be located next to the package.json file/);
+ t.throws(() => loadConfigSync({configFile: 'nested/explicit.js'}), /Config files must be located next to the package.json file/);
t.end();
});
test('throws if configFile option has an unsupported extension', t => {
changeDir('explicit-bad-extension');
- t.throws(() => loadConfig({configFile: 'explicit.txt'}), /Config files must have .js, .cjs or .mjs extensions/);
+ t.throws(() => loadConfigSync({configFile: 'explicit.txt'}), /Config files must have .js, .cjs or .mjs extensions/);
t.end();
});
@@ -58,7 +58,7 @@ test('merges in defaults passed with initial call', t => {
const defaults = {
files: ['123', '!456']
};
- const {files, failFast} = loadConfig({defaults});
+ const {files, failFast} = loadConfigSync({defaults});
t.is(failFast, true, 'preserves original props');
t.is(files, defaults.files, 'merges in extra props');
t.end();
@@ -66,51 +66,51 @@ test('merges in defaults passed with initial call', t => {
test('loads config from file with `export default` syntax', t => {
changeDir('package-no-file-yes');
- const conf = loadConfig();
+ const conf = loadConfigSync();
t.is(conf.files, 'config-file-esm-test-value');
t.end();
});
test('loads config from factory function', t => {
changeDir('package-no-file-yes-factory');
- const conf = loadConfig();
+ const conf = loadConfigSync();
t.ok(conf.files.startsWith(__dirname));
t.end();
});
test('does not support require() inside config.js files', t => {
changeDir('require');
- t.throws(loadConfig, /Error loading ava\.config\.js: require is not defined/);
+ t.throws(loadConfigSync, /Error loading ava\.config\.js: require is not defined/);
t.end();
});
test('throws an error if a config factory returns a promise', t => {
changeDir('factory-no-promise-return');
- t.throws(loadConfig, /Factory method exported by ava.config.js must not return a promise/);
+ t.throws(loadConfigSync, /Factory method exported by ava.config.js must not return a promise/);
t.end();
});
test('throws an error if a config exports a promise', t => {
changeDir('no-promise-config');
- t.throws(loadConfig, /ava.config.js must not export a promise/);
+ t.throws(loadConfigSync, /ava.config.js must not export a promise/);
t.end();
});
test('throws an error if a config factory does not return a plain object', t => {
changeDir('factory-no-plain-return');
- t.throws(loadConfig, /Factory method exported by ava.config.js must return a plain object/);
+ t.throws(loadConfigSync, /Factory method exported by ava.config.js must return a plain object/);
t.end();
});
test('throws an error if a config does not export a plain object', t => {
changeDir('no-plain-config');
- t.throws(loadConfig, /ava.config.js must export a plain object or factory function/);
+ t.throws(loadConfigSync, /ava.config.js must export a plain object or factory function/);
t.end();
});
test('receives a `projectDir` property', t => {
changeDir('package-only');
- const conf = loadConfig();
+ const conf = loadConfigSync();
t.ok(conf.projectDir.startsWith(__dirname));
t.end();
});
@@ -119,7 +119,7 @@ test('rethrows wrapped module errors', t => {
t.plan(1);
changeDir('throws');
try {
- loadConfig();
+ loadConfigSync();
} catch (error) {
t.is(error.parent.message, 'foo');
}
@@ -127,49 +127,49 @@ test('rethrows wrapped module errors', t => {
test('throws an error if a .js config file has no default export', t => {
changeDir('no-default-export');
- t.throws(loadConfig, /ava.config.js must have a default export, using ES module syntax/);
+ t.throws(loadConfigSync, /ava.config.js must have a default export, using ES module syntax/);
t.end();
});
test('throws an error if a config file contains `ava` property', t => {
changeDir('contains-ava-property');
- t.throws(loadConfig, /Encountered ’ava’ property in ava.config.js; avoid wrapping the configuration/);
+ t.throws(loadConfigSync, /Encountered ’ava’ property in ava.config.js; avoid wrapping the configuration/);
t.end();
});
test('throws an error if a config file contains a non-object `nonSemVerExperiments` property', t => {
changeDir('non-object-experiments');
- t.throws(loadConfig, /nonSemVerExperiments from ava.config.js must be an object/);
+ t.throws(loadConfigSync, /nonSemVerExperiments from ava.config.js must be an object/);
t.end();
});
test('throws an error if a config file enables an unsupported experiment', t => {
changeDir('unsupported-experiments');
- t.throws(loadConfig, /nonSemVerExperiments.unsupported from ava.config.js is not a supported experiment/);
+ t.throws(loadConfigSync, /nonSemVerExperiments.unsupported from ava.config.js is not a supported experiment/);
t.end();
});
test('loads .cjs config', t => {
changeDir('cjs');
- const conf = loadConfig();
+ const conf = loadConfigSync();
t.ok(conf.files.startsWith(__dirname));
t.end();
});
test('throws an error if both .js and .cjs configs are present', t => {
changeDir('file-yes-cjs-yes');
- t.throws(loadConfig, /Conflicting configuration in ava.config.js and ava.config.cjs/);
+ t.throws(loadConfigSync, /Conflicting configuration in ava.config.js and ava.config.cjs/);
t.end();
});
test('refuses to load .mjs config', t => {
changeDir('mjs');
- t.throws(loadConfig, /AVA cannot yet load ava.config.mjs files/);
+ t.throws(loadConfigSync, /AVA cannot yet load ava.config.mjs files/);
t.end();
});
test('throws an error if .js, .cjs and .mjs configs are present', t => {
changeDir('file-yes-cjs-yes');
- t.throws(loadConfig, /Conflicting configuration in ava.config.js and ava.config.cjs & ava.config.mjs/);
+ t.throws(loadConfigSync, /Conflicting configuration in ava.config.js and ava.config.cjs & ava.config.mjs/);
t.end();
}, {todo: true});
diff --git a/test-tap/reporters/tap.edgecases.v10.log b/test-tap/reporters/tap.edgecases.v10.log
index 838ef9d3a..d8e0bf81a 100644
--- a/test-tap/reporters/tap.edgecases.v10.log
+++ b/test-tap/reporters/tap.edgecases.v10.log
@@ -1,9 +1,7 @@
TAP version 13
---tty-stream-chunk-separator
-# No tests found in ava-import-no-test-declaration.js
not ok 1 - No tests found in ava-import-no-test-declaration.js
---tty-stream-chunk-separator
-# TypeError: test is not a function
not ok 2 - TypeError: test is not a function
---
name: TypeError
@@ -13,13 +11,10 @@ not ok 2 - TypeError: test is not a function
(test-tap/fixture/report/edgecases/import-and-use-test-member.js:3:1)
...
---tty-stream-chunk-separator
-# import-and-use-test-member.js exited with a non-zero exit code: 1
not ok 3 - import-and-use-test-member.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
not ok 4 - No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
---tty-stream-chunk-separator
-# Error: throws
not ok 5 - Error: throws
---
name: Error
@@ -27,7 +22,6 @@ not ok 5 - Error: throws
at: 'Object. (test-tap/fixture/report/edgecases/throws.js:1:7)'
...
---tty-stream-chunk-separator
-# throws.js exited with a non-zero exit code: 1
not ok 6 - throws.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
diff --git a/test-tap/reporters/tap.edgecases.v12.log b/test-tap/reporters/tap.edgecases.v12.log
index 838ef9d3a..d8e0bf81a 100644
--- a/test-tap/reporters/tap.edgecases.v12.log
+++ b/test-tap/reporters/tap.edgecases.v12.log
@@ -1,9 +1,7 @@
TAP version 13
---tty-stream-chunk-separator
-# No tests found in ava-import-no-test-declaration.js
not ok 1 - No tests found in ava-import-no-test-declaration.js
---tty-stream-chunk-separator
-# TypeError: test is not a function
not ok 2 - TypeError: test is not a function
---
name: TypeError
@@ -13,13 +11,10 @@ not ok 2 - TypeError: test is not a function
(test-tap/fixture/report/edgecases/import-and-use-test-member.js:3:1)
...
---tty-stream-chunk-separator
-# import-and-use-test-member.js exited with a non-zero exit code: 1
not ok 3 - import-and-use-test-member.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
not ok 4 - No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
---tty-stream-chunk-separator
-# Error: throws
not ok 5 - Error: throws
---
name: Error
@@ -27,7 +22,6 @@ not ok 5 - Error: throws
at: 'Object. (test-tap/fixture/report/edgecases/throws.js:1:7)'
...
---tty-stream-chunk-separator
-# throws.js exited with a non-zero exit code: 1
not ok 6 - throws.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
diff --git a/test-tap/reporters/tap.edgecases.v14.log b/test-tap/reporters/tap.edgecases.v14.log
index 838ef9d3a..d8e0bf81a 100644
--- a/test-tap/reporters/tap.edgecases.v14.log
+++ b/test-tap/reporters/tap.edgecases.v14.log
@@ -1,9 +1,7 @@
TAP version 13
---tty-stream-chunk-separator
-# No tests found in ava-import-no-test-declaration.js
not ok 1 - No tests found in ava-import-no-test-declaration.js
---tty-stream-chunk-separator
-# TypeError: test is not a function
not ok 2 - TypeError: test is not a function
---
name: TypeError
@@ -13,13 +11,10 @@ not ok 2 - TypeError: test is not a function
(test-tap/fixture/report/edgecases/import-and-use-test-member.js:3:1)
...
---tty-stream-chunk-separator
-# import-and-use-test-member.js exited with a non-zero exit code: 1
not ok 3 - import-and-use-test-member.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
not ok 4 - No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
---tty-stream-chunk-separator
-# Error: throws
not ok 5 - Error: throws
---
name: Error
@@ -27,7 +22,6 @@ not ok 5 - Error: throws
at: 'Object. (test-tap/fixture/report/edgecases/throws.js:1:7)'
...
---tty-stream-chunk-separator
-# throws.js exited with a non-zero exit code: 1
not ok 6 - throws.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
diff --git a/test-tap/reporters/tap.edgecases.v15.log b/test-tap/reporters/tap.edgecases.v15.log
index 838ef9d3a..d8e0bf81a 100644
--- a/test-tap/reporters/tap.edgecases.v15.log
+++ b/test-tap/reporters/tap.edgecases.v15.log
@@ -1,9 +1,7 @@
TAP version 13
---tty-stream-chunk-separator
-# No tests found in ava-import-no-test-declaration.js
not ok 1 - No tests found in ava-import-no-test-declaration.js
---tty-stream-chunk-separator
-# TypeError: test is not a function
not ok 2 - TypeError: test is not a function
---
name: TypeError
@@ -13,13 +11,10 @@ not ok 2 - TypeError: test is not a function
(test-tap/fixture/report/edgecases/import-and-use-test-member.js:3:1)
...
---tty-stream-chunk-separator
-# import-and-use-test-member.js exited with a non-zero exit code: 1
not ok 3 - import-and-use-test-member.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
not ok 4 - No tests found in no-ava-import.js, make sure to import "ava" at the top of your test file
---tty-stream-chunk-separator
-# Error: throws
not ok 5 - Error: throws
---
name: Error
@@ -27,7 +22,6 @@ not ok 5 - Error: throws
at: 'Object. (test-tap/fixture/report/edgecases/throws.js:1:7)'
...
---tty-stream-chunk-separator
-# throws.js exited with a non-zero exit code: 1
not ok 6 - throws.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
diff --git a/test-tap/reporters/tap.failfast.v10.log b/test-tap/reporters/tap.failfast.v10.log
index af03c5b32..612b4bf05 100644
--- a/test-tap/reporters/tap.failfast.v10.log
+++ b/test-tap/reporters/tap.failfast.v10.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.failfast.v12.log b/test-tap/reporters/tap.failfast.v12.log
index a38a7d8ef..258c0deec 100644
--- a/test-tap/reporters/tap.failfast.v12.log
+++ b/test-tap/reporters/tap.failfast.v12.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.failfast.v14.log b/test-tap/reporters/tap.failfast.v14.log
index a38a7d8ef..258c0deec 100644
--- a/test-tap/reporters/tap.failfast.v14.log
+++ b/test-tap/reporters/tap.failfast.v14.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.failfast.v15.log b/test-tap/reporters/tap.failfast.v15.log
index a38a7d8ef..258c0deec 100644
--- a/test-tap/reporters/tap.failfast.v15.log
+++ b/test-tap/reporters/tap.failfast.v15.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.failfast2.v10.log b/test-tap/reporters/tap.failfast2.v10.log
index eb8f38c15..f1cc7fd8a 100644
--- a/test-tap/reporters/tap.failfast2.v10.log
+++ b/test-tap/reporters/tap.failfast2.v10.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.failfast2.v12.log b/test-tap/reporters/tap.failfast2.v12.log
index 4300019d7..854c9a8c0 100644
--- a/test-tap/reporters/tap.failfast2.v12.log
+++ b/test-tap/reporters/tap.failfast2.v12.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.failfast2.v14.log b/test-tap/reporters/tap.failfast2.v14.log
index 4300019d7..854c9a8c0 100644
--- a/test-tap/reporters/tap.failfast2.v14.log
+++ b/test-tap/reporters/tap.failfast2.v14.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.failfast2.v15.log b/test-tap/reporters/tap.failfast2.v15.log
index 4300019d7..854c9a8c0 100644
--- a/test-tap/reporters/tap.failfast2.v15.log
+++ b/test-tap/reporters/tap.failfast2.v15.log
@@ -1,7 +1,6 @@
TAP version 13
---tty-stream-chunk-separator
-# a › fails
-not ok 1 - a [90m[2m›[22m[39m fails
+not ok 1 - a › fails
---
name: AssertionError
message: Test failed via `t.fail()`
diff --git a/test-tap/reporters/tap.only.v10.log b/test-tap/reporters/tap.only.v10.log
index 4df4b8c60..36f42b988 100644
--- a/test-tap/reporters/tap.only.v10.log
+++ b/test-tap/reporters/tap.only.v10.log
@@ -1,10 +1,8 @@
TAP version 13
---tty-stream-chunk-separator
-# a › only
-ok 1 - a [90m[2m›[22m[39m only
+ok 1 - a › only
---tty-stream-chunk-separator
-# b › passes
-ok 2 - b [90m[2m›[22m[39m passes
+ok 2 - b › passes
---tty-stream-chunk-separator
1..2
diff --git a/test-tap/reporters/tap.only.v12.log b/test-tap/reporters/tap.only.v12.log
index 4df4b8c60..36f42b988 100644
--- a/test-tap/reporters/tap.only.v12.log
+++ b/test-tap/reporters/tap.only.v12.log
@@ -1,10 +1,8 @@
TAP version 13
---tty-stream-chunk-separator
-# a › only
-ok 1 - a [90m[2m›[22m[39m only
+ok 1 - a › only
---tty-stream-chunk-separator
-# b › passes
-ok 2 - b [90m[2m›[22m[39m passes
+ok 2 - b › passes
---tty-stream-chunk-separator
1..2
diff --git a/test-tap/reporters/tap.only.v14.log b/test-tap/reporters/tap.only.v14.log
index 4df4b8c60..36f42b988 100644
--- a/test-tap/reporters/tap.only.v14.log
+++ b/test-tap/reporters/tap.only.v14.log
@@ -1,10 +1,8 @@
TAP version 13
---tty-stream-chunk-separator
-# a › only
-ok 1 - a [90m[2m›[22m[39m only
+ok 1 - a › only
---tty-stream-chunk-separator
-# b › passes
-ok 2 - b [90m[2m›[22m[39m passes
+ok 2 - b › passes
---tty-stream-chunk-separator
1..2
diff --git a/test-tap/reporters/tap.only.v15.log b/test-tap/reporters/tap.only.v15.log
index 4df4b8c60..36f42b988 100644
--- a/test-tap/reporters/tap.only.v15.log
+++ b/test-tap/reporters/tap.only.v15.log
@@ -1,10 +1,8 @@
TAP version 13
---tty-stream-chunk-separator
-# a › only
-ok 1 - a [90m[2m›[22m[39m only
+ok 1 - a › only
---tty-stream-chunk-separator
-# b › passes
-ok 2 - b [90m[2m›[22m[39m passes
+ok 2 - b › passes
---tty-stream-chunk-separator
1..2
diff --git a/test-tap/reporters/tap.regular.v10.log b/test-tap/reporters/tap.regular.v10.log
index 376015c75..737f37817 100644
--- a/test-tap/reporters/tap.regular.v10.log
+++ b/test-tap/reporters/tap.regular.v10.log
@@ -1,6 +1,5 @@
TAP version 13
---tty-stream-chunk-separator
-# TypeError: test.serial.test is not a function
not ok 1 - TypeError: test.serial.test is not a function
---
name: TypeError
@@ -8,11 +7,9 @@ not ok 1 - TypeError: test.serial.test is not a function
at: 'Object. (test-tap/fixture/report/regular/bad-test-chain.js:3:13)'
...
---tty-stream-chunk-separator
-# bad-test-chain.js exited with a non-zero exit code: 1
not ok 2 - bad-test-chain.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# nested-objects › format with max depth 4
-not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
+not ok 3 - nested-objects › format with max depth 4
---
name: AssertionError
assertion: deepEqual
@@ -35,8 +32,7 @@ not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
at: 't (test-tap/fixture/report/regular/nested-objects.js:28:4)'
...
---tty-stream-chunk-separator
-# nested-objects › format like with max depth 4
-not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
+not ok 4 - nested-objects › format like with max depth 4
---
name: AssertionError
assertion: like
@@ -57,21 +53,19 @@ not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
---tty-stream-chunk-separator
# output-in-hook › before hook
---tty-stream-chunk-separator
- # before
+# before
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for passing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for failing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
-# output-in-hook › passing test
-ok 5 - output-in-hook [90m[2m›[22m[39m passing test
+ok 5 - output-in-hook › passing test
---tty-stream-chunk-separator
-# output-in-hook › failing test
-not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
+not ok 6 - output-in-hook › failing test
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -81,31 +75,27 @@ not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
---tty-stream-chunk-separator
# output-in-hook › afterEach hook for passing test
---tty-stream-chunk-separator
- # afterEach
+# afterEach
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for failing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for passing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › cleanup
---tty-stream-chunk-separator
- # afterAlways
+# afterAlways
---tty-stream-chunk-separator
-# test › skip
-ok 7 - test [90m[2m›[22m[39m skip # SKIP
+ok 7 - test › skip # SKIP
---tty-stream-chunk-separator
-# test › todo
-not ok 8 - test [90m[2m›[22m[39m todo # TODO
+not ok 8 - test › todo # TODO
---tty-stream-chunk-separator
-# test › passes
-ok 9 - test [90m[2m›[22m[39m passes
+ok 9 - test › passes
---tty-stream-chunk-separator
-# test › fails
-not ok 10 - test [90m[2m›[22m[39m fails
+not ok 10 - test › fails
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -113,11 +103,9 @@ not ok 10 - test [90m[2m›[22m[39m fails
at: 't (test-tap/fixture/report/regular/test.js:9:22)'
...
---tty-stream-chunk-separator
-# test › known failure
-ok 11 - test [90m[2m›[22m[39m known failure
+ok 11 - test › known failure
---tty-stream-chunk-separator
-# test › no longer failing
-not ok 12 - test [90m[2m›[22m[39m no longer failing
+not ok 12 - test › no longer failing
---
name: Error
message: >-
@@ -126,10 +114,9 @@ not ok 12 - test [90m[2m›[22m[39m no longer failing
at: ''
...
---tty-stream-chunk-separator
-# test › logs
-not ok 13 - test [90m[2m›[22m[39m logs
- * hello
- * world
+not ok 13 - test › logs
+# hello
+# world
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -137,8 +124,7 @@ not ok 13 - test [90m[2m›[22m[39m logs
at: 't (test-tap/fixture/report/regular/test.js:18:4)'
...
---tty-stream-chunk-separator
-# test › formatted
-not ok 14 - test [90m[2m›[22m[39m formatted
+not ok 14 - test › formatted
---
name: AssertionError
assertion: deepEqual
@@ -149,8 +135,7 @@ not ok 14 - test [90m[2m›[22m[39m formatted
at: 't (test-tap/fixture/report/regular/test.js:22:4)'
...
---tty-stream-chunk-separator
-# test › power-assert
-not ok 15 - test [90m[2m›[22m[39m power-assert
+not ok 15 - test › power-assert
---
name: AssertionError
assertion: assert
@@ -160,8 +145,7 @@ not ok 15 - test [90m[2m›[22m[39m power-assert
at: 't (test-tap/fixture/report/regular/test.js:27:4)'
...
---tty-stream-chunk-separator
-# test › bad throws
-not ok 16 - test [90m[2m›[22m[39m bad throws
+not ok 16 - test › bad throws
---
name: AssertionError
message: Improper usage of `t.throws()` detected
@@ -176,8 +160,7 @@ not ok 16 - test [90m[2m›[22m[39m bad throws
t (test-tap/fixture/report/regular/test.js:35:11)
...
---tty-stream-chunk-separator
-# test › bad notThrows
-not ok 17 - test [90m[2m›[22m[39m bad notThrows
+not ok 17 - test › bad notThrows
---
name: AssertionError
message: Improper usage of `t.notThrows()` detected
@@ -192,8 +175,7 @@ not ok 17 - test [90m[2m›[22m[39m bad notThrows
t (test-tap/fixture/report/regular/test.js:43:14)
...
---tty-stream-chunk-separator
-# test › implementation throws non-error
-not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
+not ok 18 - test › implementation throws non-error
---
name: AssertionError
message: Error thrown in test
@@ -202,8 +184,7 @@ not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
at: ''
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throws
-not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
+not ok 19 - traces-in-t-throws › throws
---
name: AssertionError
assertion: throws
@@ -222,8 +203,7 @@ not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
t (test-tap/fixture/report/regular/traces-in-t-throws.js:12:4)
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrows
-not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
+not ok 20 - traces-in-t-throws › notThrows
---
name: AssertionError
assertion: notThrows
@@ -241,8 +221,7 @@ not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
t (test-tap/fixture/report/regular/traces-in-t-throws.js:16:4)
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrowsAsync
-not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
+not ok 21 - traces-in-t-throws › notThrowsAsync
---
name: AssertionError
assertion: notThrowsAsync
@@ -257,8 +236,7 @@ not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
t (test-tap/fixture/report/regular/traces-in-t-throws.js:20:4)
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync
-not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
+not ok 22 - traces-in-t-throws › throwsAsync
---
name: AssertionError
assertion: throwsAsync
@@ -273,8 +251,7 @@ not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
t (test-tap/fixture/report/regular/traces-in-t-throws.js:24:4)
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync different error
-not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different error
+not ok 23 - traces-in-t-throws › throwsAsync different error
---
name: AssertionError
assertion: throwsAsync
@@ -291,10 +268,8 @@ not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different erro
t (test-tap/fixture/report/regular/traces-in-t-throws.js:28:11)
...
---tty-stream-chunk-separator
-# uncaught-exception › passes
-ok 24 - uncaught-exception [90m[2m›[22m[39m passes
+ok 24 - uncaught-exception › passes
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 25 - Error: Can’t catch me
---
name: Error
@@ -304,16 +279,12 @@ not ok 25 - Error: Can’t catch me
(test-tap/fixture/report/regular/uncaught-exception.js:5:9)
...
---tty-stream-chunk-separator
-# uncaught-exception.js exited with a non-zero exit code: 1
not ok 26 - uncaught-exception.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# unhandled-rejection › passes
-ok 27 - unhandled-rejection [90m[2m›[22m[39m passes
+ok 27 - unhandled-rejection › passes
---tty-stream-chunk-separator
-# unhandled-rejection › unhandled non-error rejection
-ok 28 - unhandled-rejection [90m[2m›[22m[39m unhandled non-error rejection
+ok 28 - unhandled-rejection › unhandled non-error rejection
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 29 - Error: Can’t catch me
---
name: Error
@@ -321,7 +292,6 @@ not ok 29 - Error: Can’t catch me
at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.js:4:17)'
...
---tty-stream-chunk-separator
-# unhandled-rejection
not ok 30 - unhandled-rejection
---
message: Non-error object
diff --git a/test-tap/reporters/tap.regular.v12.log b/test-tap/reporters/tap.regular.v12.log
index 3361eaf98..a8ab2f46a 100644
--- a/test-tap/reporters/tap.regular.v12.log
+++ b/test-tap/reporters/tap.regular.v12.log
@@ -1,6 +1,5 @@
TAP version 13
---tty-stream-chunk-separator
-# TypeError: test.serial.test is not a function
not ok 1 - TypeError: test.serial.test is not a function
---
name: TypeError
@@ -8,11 +7,9 @@ not ok 1 - TypeError: test.serial.test is not a function
at: 'Object. (test-tap/fixture/report/regular/bad-test-chain.js:3:13)'
...
---tty-stream-chunk-separator
-# bad-test-chain.js exited with a non-zero exit code: 1
not ok 2 - bad-test-chain.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# nested-objects › format with max depth 4
-not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
+not ok 3 - nested-objects › format with max depth 4
---
name: AssertionError
assertion: deepEqual
@@ -35,8 +32,7 @@ not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
at: 'test-tap/fixture/report/regular/nested-objects.js:28:4'
...
---tty-stream-chunk-separator
-# nested-objects › format like with max depth 4
-not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
+not ok 4 - nested-objects › format like with max depth 4
---
name: AssertionError
assertion: like
@@ -57,21 +53,19 @@ not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
---tty-stream-chunk-separator
# output-in-hook › before hook
---tty-stream-chunk-separator
- # before
+# before
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for passing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for failing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
-# output-in-hook › passing test
-ok 5 - output-in-hook [90m[2m›[22m[39m passing test
+ok 5 - output-in-hook › passing test
---tty-stream-chunk-separator
-# output-in-hook › failing test
-not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
+not ok 6 - output-in-hook › failing test
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -81,31 +75,27 @@ not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
---tty-stream-chunk-separator
# output-in-hook › afterEach hook for passing test
---tty-stream-chunk-separator
- # afterEach
+# afterEach
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for failing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for passing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › cleanup
---tty-stream-chunk-separator
- # afterAlways
+# afterAlways
---tty-stream-chunk-separator
-# test › skip
-ok 7 - test [90m[2m›[22m[39m skip # SKIP
+ok 7 - test › skip # SKIP
---tty-stream-chunk-separator
-# test › todo
-not ok 8 - test [90m[2m›[22m[39m todo # TODO
+not ok 8 - test › todo # TODO
---tty-stream-chunk-separator
-# test › passes
-ok 9 - test [90m[2m›[22m[39m passes
+ok 9 - test › passes
---tty-stream-chunk-separator
-# test › fails
-not ok 10 - test [90m[2m›[22m[39m fails
+not ok 10 - test › fails
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -113,11 +103,9 @@ not ok 10 - test [90m[2m›[22m[39m fails
at: 'test-tap/fixture/report/regular/test.js:9:22'
...
---tty-stream-chunk-separator
-# test › known failure
-ok 11 - test [90m[2m›[22m[39m known failure
+ok 11 - test › known failure
---tty-stream-chunk-separator
-# test › no longer failing
-not ok 12 - test [90m[2m›[22m[39m no longer failing
+not ok 12 - test › no longer failing
---
name: Error
message: >-
@@ -126,10 +114,9 @@ not ok 12 - test [90m[2m›[22m[39m no longer failing
at: ''
...
---tty-stream-chunk-separator
-# test › logs
-not ok 13 - test [90m[2m›[22m[39m logs
- * hello
- * world
+not ok 13 - test › logs
+# hello
+# world
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -137,8 +124,7 @@ not ok 13 - test [90m[2m›[22m[39m logs
at: 'test-tap/fixture/report/regular/test.js:18:4'
...
---tty-stream-chunk-separator
-# test › formatted
-not ok 14 - test [90m[2m›[22m[39m formatted
+not ok 14 - test › formatted
---
name: AssertionError
assertion: deepEqual
@@ -149,8 +135,7 @@ not ok 14 - test [90m[2m›[22m[39m formatted
at: 'test-tap/fixture/report/regular/test.js:22:4'
...
---tty-stream-chunk-separator
-# test › power-assert
-not ok 15 - test [90m[2m›[22m[39m power-assert
+not ok 15 - test › power-assert
---
name: AssertionError
assertion: assert
@@ -160,8 +145,7 @@ not ok 15 - test [90m[2m›[22m[39m power-assert
at: 'test-tap/fixture/report/regular/test.js:27:4'
...
---tty-stream-chunk-separator
-# test › bad throws
-not ok 16 - test [90m[2m›[22m[39m bad throws
+not ok 16 - test › bad throws
---
name: AssertionError
message: Improper usage of `t.throws()` detected
@@ -176,8 +160,7 @@ not ok 16 - test [90m[2m›[22m[39m bad throws
test-tap/fixture/report/regular/test.js:35:11
...
---tty-stream-chunk-separator
-# test › bad notThrows
-not ok 17 - test [90m[2m›[22m[39m bad notThrows
+not ok 17 - test › bad notThrows
---
name: AssertionError
message: Improper usage of `t.notThrows()` detected
@@ -192,8 +175,7 @@ not ok 17 - test [90m[2m›[22m[39m bad notThrows
test-tap/fixture/report/regular/test.js:43:14
...
---tty-stream-chunk-separator
-# test › implementation throws non-error
-not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
+not ok 18 - test › implementation throws non-error
---
name: AssertionError
message: Error thrown in test
@@ -202,8 +184,7 @@ not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
at: ''
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throws
-not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
+not ok 19 - traces-in-t-throws › throws
---
name: AssertionError
assertion: throws
@@ -219,8 +200,7 @@ not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
test-tap/fixture/report/regular/traces-in-t-throws.js:12:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrows
-not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
+not ok 20 - traces-in-t-throws › notThrows
---
name: AssertionError
assertion: notThrows
@@ -235,8 +215,7 @@ not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
test-tap/fixture/report/regular/traces-in-t-throws.js:16:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrowsAsync
-not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
+not ok 21 - traces-in-t-throws › notThrowsAsync
---
name: AssertionError
assertion: notThrowsAsync
@@ -251,8 +230,7 @@ not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
test-tap/fixture/report/regular/traces-in-t-throws.js:20:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync
-not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
+not ok 22 - traces-in-t-throws › throwsAsync
---
name: AssertionError
assertion: throwsAsync
@@ -270,8 +248,7 @@ not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
test-tap/fixture/report/regular/traces-in-t-throws.js:24:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync different error
-not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different error
+not ok 23 - traces-in-t-throws › throwsAsync different error
---
name: AssertionError
assertion: throwsAsync
@@ -288,10 +265,8 @@ not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different erro
test-tap/fixture/report/regular/traces-in-t-throws.js:28:11
...
---tty-stream-chunk-separator
-# uncaught-exception › passes
-ok 24 - uncaught-exception [90m[2m›[22m[39m passes
+ok 24 - uncaught-exception › passes
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 25 - Error: Can’t catch me
---
name: Error
@@ -301,16 +276,12 @@ not ok 25 - Error: Can’t catch me
(test-tap/fixture/report/regular/uncaught-exception.js:5:9)
...
---tty-stream-chunk-separator
-# uncaught-exception.js exited with a non-zero exit code: 1
not ok 26 - uncaught-exception.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# unhandled-rejection › passes
-ok 27 - unhandled-rejection [90m[2m›[22m[39m passes
+ok 27 - unhandled-rejection › passes
---tty-stream-chunk-separator
-# unhandled-rejection › unhandled non-error rejection
-ok 28 - unhandled-rejection [90m[2m›[22m[39m unhandled non-error rejection
+ok 28 - unhandled-rejection › unhandled non-error rejection
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 29 - Error: Can’t catch me
---
name: Error
@@ -318,7 +289,6 @@ not ok 29 - Error: Can’t catch me
at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.js:4:17)'
...
---tty-stream-chunk-separator
-# unhandled-rejection
not ok 30 - unhandled-rejection
---
message: Non-error object
diff --git a/test-tap/reporters/tap.regular.v14.log b/test-tap/reporters/tap.regular.v14.log
index 3361eaf98..a8ab2f46a 100644
--- a/test-tap/reporters/tap.regular.v14.log
+++ b/test-tap/reporters/tap.regular.v14.log
@@ -1,6 +1,5 @@
TAP version 13
---tty-stream-chunk-separator
-# TypeError: test.serial.test is not a function
not ok 1 - TypeError: test.serial.test is not a function
---
name: TypeError
@@ -8,11 +7,9 @@ not ok 1 - TypeError: test.serial.test is not a function
at: 'Object. (test-tap/fixture/report/regular/bad-test-chain.js:3:13)'
...
---tty-stream-chunk-separator
-# bad-test-chain.js exited with a non-zero exit code: 1
not ok 2 - bad-test-chain.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# nested-objects › format with max depth 4
-not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
+not ok 3 - nested-objects › format with max depth 4
---
name: AssertionError
assertion: deepEqual
@@ -35,8 +32,7 @@ not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
at: 'test-tap/fixture/report/regular/nested-objects.js:28:4'
...
---tty-stream-chunk-separator
-# nested-objects › format like with max depth 4
-not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
+not ok 4 - nested-objects › format like with max depth 4
---
name: AssertionError
assertion: like
@@ -57,21 +53,19 @@ not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
---tty-stream-chunk-separator
# output-in-hook › before hook
---tty-stream-chunk-separator
- # before
+# before
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for passing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for failing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
-# output-in-hook › passing test
-ok 5 - output-in-hook [90m[2m›[22m[39m passing test
+ok 5 - output-in-hook › passing test
---tty-stream-chunk-separator
-# output-in-hook › failing test
-not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
+not ok 6 - output-in-hook › failing test
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -81,31 +75,27 @@ not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
---tty-stream-chunk-separator
# output-in-hook › afterEach hook for passing test
---tty-stream-chunk-separator
- # afterEach
+# afterEach
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for failing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for passing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › cleanup
---tty-stream-chunk-separator
- # afterAlways
+# afterAlways
---tty-stream-chunk-separator
-# test › skip
-ok 7 - test [90m[2m›[22m[39m skip # SKIP
+ok 7 - test › skip # SKIP
---tty-stream-chunk-separator
-# test › todo
-not ok 8 - test [90m[2m›[22m[39m todo # TODO
+not ok 8 - test › todo # TODO
---tty-stream-chunk-separator
-# test › passes
-ok 9 - test [90m[2m›[22m[39m passes
+ok 9 - test › passes
---tty-stream-chunk-separator
-# test › fails
-not ok 10 - test [90m[2m›[22m[39m fails
+not ok 10 - test › fails
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -113,11 +103,9 @@ not ok 10 - test [90m[2m›[22m[39m fails
at: 'test-tap/fixture/report/regular/test.js:9:22'
...
---tty-stream-chunk-separator
-# test › known failure
-ok 11 - test [90m[2m›[22m[39m known failure
+ok 11 - test › known failure
---tty-stream-chunk-separator
-# test › no longer failing
-not ok 12 - test [90m[2m›[22m[39m no longer failing
+not ok 12 - test › no longer failing
---
name: Error
message: >-
@@ -126,10 +114,9 @@ not ok 12 - test [90m[2m›[22m[39m no longer failing
at: ''
...
---tty-stream-chunk-separator
-# test › logs
-not ok 13 - test [90m[2m›[22m[39m logs
- * hello
- * world
+not ok 13 - test › logs
+# hello
+# world
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -137,8 +124,7 @@ not ok 13 - test [90m[2m›[22m[39m logs
at: 'test-tap/fixture/report/regular/test.js:18:4'
...
---tty-stream-chunk-separator
-# test › formatted
-not ok 14 - test [90m[2m›[22m[39m formatted
+not ok 14 - test › formatted
---
name: AssertionError
assertion: deepEqual
@@ -149,8 +135,7 @@ not ok 14 - test [90m[2m›[22m[39m formatted
at: 'test-tap/fixture/report/regular/test.js:22:4'
...
---tty-stream-chunk-separator
-# test › power-assert
-not ok 15 - test [90m[2m›[22m[39m power-assert
+not ok 15 - test › power-assert
---
name: AssertionError
assertion: assert
@@ -160,8 +145,7 @@ not ok 15 - test [90m[2m›[22m[39m power-assert
at: 'test-tap/fixture/report/regular/test.js:27:4'
...
---tty-stream-chunk-separator
-# test › bad throws
-not ok 16 - test [90m[2m›[22m[39m bad throws
+not ok 16 - test › bad throws
---
name: AssertionError
message: Improper usage of `t.throws()` detected
@@ -176,8 +160,7 @@ not ok 16 - test [90m[2m›[22m[39m bad throws
test-tap/fixture/report/regular/test.js:35:11
...
---tty-stream-chunk-separator
-# test › bad notThrows
-not ok 17 - test [90m[2m›[22m[39m bad notThrows
+not ok 17 - test › bad notThrows
---
name: AssertionError
message: Improper usage of `t.notThrows()` detected
@@ -192,8 +175,7 @@ not ok 17 - test [90m[2m›[22m[39m bad notThrows
test-tap/fixture/report/regular/test.js:43:14
...
---tty-stream-chunk-separator
-# test › implementation throws non-error
-not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
+not ok 18 - test › implementation throws non-error
---
name: AssertionError
message: Error thrown in test
@@ -202,8 +184,7 @@ not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
at: ''
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throws
-not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
+not ok 19 - traces-in-t-throws › throws
---
name: AssertionError
assertion: throws
@@ -219,8 +200,7 @@ not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
test-tap/fixture/report/regular/traces-in-t-throws.js:12:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrows
-not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
+not ok 20 - traces-in-t-throws › notThrows
---
name: AssertionError
assertion: notThrows
@@ -235,8 +215,7 @@ not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
test-tap/fixture/report/regular/traces-in-t-throws.js:16:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrowsAsync
-not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
+not ok 21 - traces-in-t-throws › notThrowsAsync
---
name: AssertionError
assertion: notThrowsAsync
@@ -251,8 +230,7 @@ not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
test-tap/fixture/report/regular/traces-in-t-throws.js:20:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync
-not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
+not ok 22 - traces-in-t-throws › throwsAsync
---
name: AssertionError
assertion: throwsAsync
@@ -270,8 +248,7 @@ not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
test-tap/fixture/report/regular/traces-in-t-throws.js:24:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync different error
-not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different error
+not ok 23 - traces-in-t-throws › throwsAsync different error
---
name: AssertionError
assertion: throwsAsync
@@ -288,10 +265,8 @@ not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different erro
test-tap/fixture/report/regular/traces-in-t-throws.js:28:11
...
---tty-stream-chunk-separator
-# uncaught-exception › passes
-ok 24 - uncaught-exception [90m[2m›[22m[39m passes
+ok 24 - uncaught-exception › passes
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 25 - Error: Can’t catch me
---
name: Error
@@ -301,16 +276,12 @@ not ok 25 - Error: Can’t catch me
(test-tap/fixture/report/regular/uncaught-exception.js:5:9)
...
---tty-stream-chunk-separator
-# uncaught-exception.js exited with a non-zero exit code: 1
not ok 26 - uncaught-exception.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# unhandled-rejection › passes
-ok 27 - unhandled-rejection [90m[2m›[22m[39m passes
+ok 27 - unhandled-rejection › passes
---tty-stream-chunk-separator
-# unhandled-rejection › unhandled non-error rejection
-ok 28 - unhandled-rejection [90m[2m›[22m[39m unhandled non-error rejection
+ok 28 - unhandled-rejection › unhandled non-error rejection
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 29 - Error: Can’t catch me
---
name: Error
@@ -318,7 +289,6 @@ not ok 29 - Error: Can’t catch me
at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.js:4:17)'
...
---tty-stream-chunk-separator
-# unhandled-rejection
not ok 30 - unhandled-rejection
---
message: Non-error object
diff --git a/test-tap/reporters/tap.regular.v15.log b/test-tap/reporters/tap.regular.v15.log
index 3361eaf98..a8ab2f46a 100644
--- a/test-tap/reporters/tap.regular.v15.log
+++ b/test-tap/reporters/tap.regular.v15.log
@@ -1,6 +1,5 @@
TAP version 13
---tty-stream-chunk-separator
-# TypeError: test.serial.test is not a function
not ok 1 - TypeError: test.serial.test is not a function
---
name: TypeError
@@ -8,11 +7,9 @@ not ok 1 - TypeError: test.serial.test is not a function
at: 'Object. (test-tap/fixture/report/regular/bad-test-chain.js:3:13)'
...
---tty-stream-chunk-separator
-# bad-test-chain.js exited with a non-zero exit code: 1
not ok 2 - bad-test-chain.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# nested-objects › format with max depth 4
-not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
+not ok 3 - nested-objects › format with max depth 4
---
name: AssertionError
assertion: deepEqual
@@ -35,8 +32,7 @@ not ok 3 - nested-objects [90m[2m›[22m[39m format with max depth 4
at: 'test-tap/fixture/report/regular/nested-objects.js:28:4'
...
---tty-stream-chunk-separator
-# nested-objects › format like with max depth 4
-not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
+not ok 4 - nested-objects › format like with max depth 4
---
name: AssertionError
assertion: like
@@ -57,21 +53,19 @@ not ok 4 - nested-objects [90m[2m›[22m[39m format like with max depth 4
---tty-stream-chunk-separator
# output-in-hook › before hook
---tty-stream-chunk-separator
- # before
+# before
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for passing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
# output-in-hook › beforeEach hook for failing test
---tty-stream-chunk-separator
- # beforeEach
+# beforeEach
---tty-stream-chunk-separator
-# output-in-hook › passing test
-ok 5 - output-in-hook [90m[2m›[22m[39m passing test
+ok 5 - output-in-hook › passing test
---tty-stream-chunk-separator
-# output-in-hook › failing test
-not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
+not ok 6 - output-in-hook › failing test
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -81,31 +75,27 @@ not ok 6 - output-in-hook [90m[2m›[22m[39m failing test
---tty-stream-chunk-separator
# output-in-hook › afterEach hook for passing test
---tty-stream-chunk-separator
- # afterEach
+# afterEach
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for failing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › afterEach.always hook for passing test
---tty-stream-chunk-separator
- # afterEachAlways
+# afterEachAlways
---tty-stream-chunk-separator
# output-in-hook › cleanup
---tty-stream-chunk-separator
- # afterAlways
+# afterAlways
---tty-stream-chunk-separator
-# test › skip
-ok 7 - test [90m[2m›[22m[39m skip # SKIP
+ok 7 - test › skip # SKIP
---tty-stream-chunk-separator
-# test › todo
-not ok 8 - test [90m[2m›[22m[39m todo # TODO
+not ok 8 - test › todo # TODO
---tty-stream-chunk-separator
-# test › passes
-ok 9 - test [90m[2m›[22m[39m passes
+ok 9 - test › passes
---tty-stream-chunk-separator
-# test › fails
-not ok 10 - test [90m[2m›[22m[39m fails
+not ok 10 - test › fails
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -113,11 +103,9 @@ not ok 10 - test [90m[2m›[22m[39m fails
at: 'test-tap/fixture/report/regular/test.js:9:22'
...
---tty-stream-chunk-separator
-# test › known failure
-ok 11 - test [90m[2m›[22m[39m known failure
+ok 11 - test › known failure
---tty-stream-chunk-separator
-# test › no longer failing
-not ok 12 - test [90m[2m›[22m[39m no longer failing
+not ok 12 - test › no longer failing
---
name: Error
message: >-
@@ -126,10 +114,9 @@ not ok 12 - test [90m[2m›[22m[39m no longer failing
at: ''
...
---tty-stream-chunk-separator
-# test › logs
-not ok 13 - test [90m[2m›[22m[39m logs
- * hello
- * world
+not ok 13 - test › logs
+# hello
+# world
---
name: AssertionError
message: Test failed via `t.fail()`
@@ -137,8 +124,7 @@ not ok 13 - test [90m[2m›[22m[39m logs
at: 'test-tap/fixture/report/regular/test.js:18:4'
...
---tty-stream-chunk-separator
-# test › formatted
-not ok 14 - test [90m[2m›[22m[39m formatted
+not ok 14 - test › formatted
---
name: AssertionError
assertion: deepEqual
@@ -149,8 +135,7 @@ not ok 14 - test [90m[2m›[22m[39m formatted
at: 'test-tap/fixture/report/regular/test.js:22:4'
...
---tty-stream-chunk-separator
-# test › power-assert
-not ok 15 - test [90m[2m›[22m[39m power-assert
+not ok 15 - test › power-assert
---
name: AssertionError
assertion: assert
@@ -160,8 +145,7 @@ not ok 15 - test [90m[2m›[22m[39m power-assert
at: 'test-tap/fixture/report/regular/test.js:27:4'
...
---tty-stream-chunk-separator
-# test › bad throws
-not ok 16 - test [90m[2m›[22m[39m bad throws
+not ok 16 - test › bad throws
---
name: AssertionError
message: Improper usage of `t.throws()` detected
@@ -176,8 +160,7 @@ not ok 16 - test [90m[2m›[22m[39m bad throws
test-tap/fixture/report/regular/test.js:35:11
...
---tty-stream-chunk-separator
-# test › bad notThrows
-not ok 17 - test [90m[2m›[22m[39m bad notThrows
+not ok 17 - test › bad notThrows
---
name: AssertionError
message: Improper usage of `t.notThrows()` detected
@@ -192,8 +175,7 @@ not ok 17 - test [90m[2m›[22m[39m bad notThrows
test-tap/fixture/report/regular/test.js:43:14
...
---tty-stream-chunk-separator
-# test › implementation throws non-error
-not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
+not ok 18 - test › implementation throws non-error
---
name: AssertionError
message: Error thrown in test
@@ -202,8 +184,7 @@ not ok 18 - test [90m[2m›[22m[39m implementation throws non-error
at: ''
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throws
-not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
+not ok 19 - traces-in-t-throws › throws
---
name: AssertionError
assertion: throws
@@ -219,8 +200,7 @@ not ok 19 - traces-in-t-throws [90m[2m›[22m[39m throws
test-tap/fixture/report/regular/traces-in-t-throws.js:12:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrows
-not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
+not ok 20 - traces-in-t-throws › notThrows
---
name: AssertionError
assertion: notThrows
@@ -235,8 +215,7 @@ not ok 20 - traces-in-t-throws [90m[2m›[22m[39m notThrows
test-tap/fixture/report/regular/traces-in-t-throws.js:16:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › notThrowsAsync
-not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
+not ok 21 - traces-in-t-throws › notThrowsAsync
---
name: AssertionError
assertion: notThrowsAsync
@@ -251,8 +230,7 @@ not ok 21 - traces-in-t-throws [90m[2m›[22m[39m notThrowsAsync
test-tap/fixture/report/regular/traces-in-t-throws.js:20:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync
-not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
+not ok 22 - traces-in-t-throws › throwsAsync
---
name: AssertionError
assertion: throwsAsync
@@ -270,8 +248,7 @@ not ok 22 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync
test-tap/fixture/report/regular/traces-in-t-throws.js:24:4
...
---tty-stream-chunk-separator
-# traces-in-t-throws › throwsAsync different error
-not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different error
+not ok 23 - traces-in-t-throws › throwsAsync different error
---
name: AssertionError
assertion: throwsAsync
@@ -288,10 +265,8 @@ not ok 23 - traces-in-t-throws [90m[2m›[22m[39m throwsAsync different erro
test-tap/fixture/report/regular/traces-in-t-throws.js:28:11
...
---tty-stream-chunk-separator
-# uncaught-exception › passes
-ok 24 - uncaught-exception [90m[2m›[22m[39m passes
+ok 24 - uncaught-exception › passes
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 25 - Error: Can’t catch me
---
name: Error
@@ -301,16 +276,12 @@ not ok 25 - Error: Can’t catch me
(test-tap/fixture/report/regular/uncaught-exception.js:5:9)
...
---tty-stream-chunk-separator
-# uncaught-exception.js exited with a non-zero exit code: 1
not ok 26 - uncaught-exception.js exited with a non-zero exit code: 1
---tty-stream-chunk-separator
-# unhandled-rejection › passes
-ok 27 - unhandled-rejection [90m[2m›[22m[39m passes
+ok 27 - unhandled-rejection › passes
---tty-stream-chunk-separator
-# unhandled-rejection › unhandled non-error rejection
-ok 28 - unhandled-rejection [90m[2m›[22m[39m unhandled non-error rejection
+ok 28 - unhandled-rejection › unhandled non-error rejection
---tty-stream-chunk-separator
-# Error: Can’t catch me
not ok 29 - Error: Can’t catch me
---
name: Error
@@ -318,7 +289,6 @@ not ok 29 - Error: Can’t catch me
at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.js:4:17)'
...
---tty-stream-chunk-separator
-# unhandled-rejection
not ok 30 - unhandled-rejection
---
message: Non-error object
diff --git a/test-tap/test.js b/test-tap/test.js
index 4b648d990..58f7dbc33 100644
--- a/test-tap/test.js
+++ b/test-tap/test.js
@@ -696,6 +696,36 @@ test('snapshot assertion can be skipped', t => {
});
});
+// Snapshots reused from test/assert.js
+test('snapshot assertions call options.skipSnapshot when skipped', async t => {
+ const projectDir = path.join(__dirname, 'fixture');
+ const manager = snapshotManager.load({
+ file: path.join(projectDir, 'assert.js'),
+ projectDir,
+ fixedLocation: null,
+ updating: false
+ });
+
+ const skipSnapshot = sinon.spy();
+
+ const test = new Test({
+ compareTestSnapshot: options => manager.compare(options),
+ skipSnapshot,
+ updateSnapshots: false,
+ metadata: {},
+ title: 'passes',
+ fn(t) {
+ t.snapshot.skip({not: {a: 'match'}});
+ t.snapshot.skip({not: {b: 'match'}});
+ t.snapshot(React.createElement(HelloMessage, {name: 'Sindre'}));
+ }
+ });
+
+ await test.run();
+
+ t.true(skipSnapshot.calledTwice);
+});
+
test('snapshot assertion cannot be skipped when updating snapshots', t => {
return new Test({
updateSnapshots: true,
diff --git a/test/concurrency/snapshots/test.js.md b/test/concurrency/snapshots/test.js.md
index 16c01cfbe..9a5c607c6 100644
--- a/test/concurrency/snapshots/test.js.md
+++ b/test/concurrency/snapshots/test.js.md
@@ -4,7 +4,7 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## bails when --concurrency is provided with an input that is a float
+## bails when --concurrency is provided without value
> fails with message
@@ -16,13 +16,13 @@ Generated by [AVA](https://avajs.dev).
'The --concurrency or -c flag must be provided with a nonnegative integer.'
-## bails when --concurrency is provided with an input that is negative
+## bails when --concurrency is provided with an input that is a float
> fails with message
'The --concurrency or -c flag must be provided with a nonnegative integer.'
-## bails when --concurrency is provided without value
+## bails when --concurrency is provided with an input that is negative
> fails with message
diff --git a/test/concurrency/snapshots/test.js.snap b/test/concurrency/snapshots/test.js.snap
index 816ed9100..322e0edf4 100644
Binary files a/test/concurrency/snapshots/test.js.snap and b/test/concurrency/snapshots/test.js.snap differ
diff --git a/test/config/fixtures/factory-promise-return/ava.config.js b/test/config/fixtures/factory-promise-return/ava.config.js
new file mode 100644
index 000000000..25171edc2
--- /dev/null
+++ b/test/config/fixtures/factory-promise-return/ava.config.js
@@ -0,0 +1,8 @@
+module.exports = async () => {
+ return {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+ };
+};
diff --git a/test/config/fixtures/factory-promise-return/package.json b/test/config/fixtures/factory-promise-return/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/config/fixtures/factory-promise-return/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.cjs b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.cjs
new file mode 100644
index 000000000..358af79e4
--- /dev/null
+++ b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.cjs
@@ -0,0 +1,3 @@
+module.exports = {
+ files: 'package-yes-files-yes-test-value'
+};
diff --git a/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.js b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.js
new file mode 100644
index 000000000..c6ddbbed4
--- /dev/null
+++ b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.js
@@ -0,0 +1,3 @@
+export default {
+ files: 'package-yes-files-yes-test-value'
+};
diff --git a/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.mjs b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.mjs
new file mode 100644
index 000000000..951c53310
--- /dev/null
+++ b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/ava.config.mjs
@@ -0,0 +1,6 @@
+export default {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ files: 'package-yes-files-yes-test-value'
+};
diff --git a/test/config/fixtures/file-yes-cjs-yes-mjs-yes/package.json b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/config/fixtures/file-yes-cjs-yes-mjs-yes/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/config/fixtures/js-as-cjs/ava.config.js b/test/config/fixtures/js-as-cjs/ava.config.js
new file mode 100644
index 000000000..c0964d0da
--- /dev/null
+++ b/test/config/fixtures/js-as-cjs/ava.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+};
diff --git a/test/config/fixtures/js-as-cjs/package.json b/test/config/fixtures/js-as-cjs/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/config/fixtures/js-as-cjs/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/config/fixtures/js-as-esm/ava.config.js b/test/config/fixtures/js-as-esm/ava.config.js
new file mode 100644
index 000000000..414e3e612
--- /dev/null
+++ b/test/config/fixtures/js-as-esm/ava.config.js
@@ -0,0 +1,6 @@
+export default {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+};
diff --git a/test/config/fixtures/js-as-esm/error.js b/test/config/fixtures/js-as-esm/error.js
new file mode 100644
index 000000000..a92906214
--- /dev/null
+++ b/test/config/fixtures/js-as-esm/error.js
@@ -0,0 +1,8 @@
+export default {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+};
+
+throw new Error('🙈');
diff --git a/test/config/fixtures/js-as-esm/no-default-export.js b/test/config/fixtures/js-as-esm/no-default-export.js
new file mode 100644
index 000000000..d5c0b831b
--- /dev/null
+++ b/test/config/fixtures/js-as-esm/no-default-export.js
@@ -0,0 +1,6 @@
+export const config = {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+};
diff --git a/test/config/fixtures/js-as-esm/package.json b/test/config/fixtures/js-as-esm/package.json
new file mode 100644
index 000000000..bedb411a9
--- /dev/null
+++ b/test/config/fixtures/js-as-esm/package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/test/config/fixtures/mjs-with-tests/ava.config.mjs b/test/config/fixtures/mjs-with-tests/ava.config.mjs
new file mode 100644
index 000000000..1dcd338ba
--- /dev/null
+++ b/test/config/fixtures/mjs-with-tests/ava.config.mjs
@@ -0,0 +1,6 @@
+export default {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ files: ['dir-a/*.js']
+};
diff --git a/test/config/fixtures/resolve-pkg-dir/dir-a-wrapper/dir-a/dir-a-wrapper-3.js b/test/config/fixtures/mjs-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-3.js
similarity index 100%
rename from test/config/fixtures/resolve-pkg-dir/dir-a-wrapper/dir-a/dir-a-wrapper-3.js
rename to test/config/fixtures/mjs-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-3.js
diff --git a/test/config/fixtures/resolve-pkg-dir/dir-a-wrapper/dir-a/dir-a-wrapper-4.js b/test/config/fixtures/mjs-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-4.js
similarity index 100%
rename from test/config/fixtures/resolve-pkg-dir/dir-a-wrapper/dir-a/dir-a-wrapper-4.js
rename to test/config/fixtures/mjs-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-4.js
diff --git a/test/config/fixtures/resolve-pkg-dir/dir-a/dir-a-base-1.js b/test/config/fixtures/mjs-with-tests/dir-a/dir-a-base-1.js
similarity index 100%
rename from test/config/fixtures/resolve-pkg-dir/dir-a/dir-a-base-1.js
rename to test/config/fixtures/mjs-with-tests/dir-a/dir-a-base-1.js
diff --git a/test/config/fixtures/resolve-pkg-dir/dir-a/dir-a-base-2.js b/test/config/fixtures/mjs-with-tests/dir-a/dir-a-base-2.js
similarity index 100%
rename from test/config/fixtures/resolve-pkg-dir/dir-a/dir-a-base-2.js
rename to test/config/fixtures/mjs-with-tests/dir-a/dir-a-base-2.js
diff --git a/test/config/fixtures/mjs-with-tests/package.json b/test/config/fixtures/mjs-with-tests/package.json
new file mode 100644
index 000000000..9992cb44e
--- /dev/null
+++ b/test/config/fixtures/mjs-with-tests/package.json
@@ -0,0 +1,4 @@
+{
+ "name": "application-name",
+ "version": "0.0.1"
+}
diff --git a/test/config/fixtures/mjs/ava.config.mjs b/test/config/fixtures/mjs/ava.config.mjs
new file mode 100644
index 000000000..414e3e612
--- /dev/null
+++ b/test/config/fixtures/mjs/ava.config.mjs
@@ -0,0 +1,6 @@
+export default {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+};
diff --git a/test/config/fixtures/mjs/error.mjs b/test/config/fixtures/mjs/error.mjs
new file mode 100644
index 000000000..a92906214
--- /dev/null
+++ b/test/config/fixtures/mjs/error.mjs
@@ -0,0 +1,8 @@
+export default {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+};
+
+throw new Error('🙈');
diff --git a/test/config/fixtures/mjs/no-default-export.mjs b/test/config/fixtures/mjs/no-default-export.mjs
new file mode 100644
index 000000000..d5c0b831b
--- /dev/null
+++ b/test/config/fixtures/mjs/no-default-export.mjs
@@ -0,0 +1,6 @@
+export const config = {
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+};
diff --git a/test/config/fixtures/mjs/package.json b/test/config/fixtures/mjs/package.json
new file mode 100644
index 000000000..bedb411a9
--- /dev/null
+++ b/test/config/fixtures/mjs/package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/test/config/fixtures/pkg-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-3.js b/test/config/fixtures/pkg-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-3.js
new file mode 100644
index 000000000..159662d3d
--- /dev/null
+++ b/test/config/fixtures/pkg-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-3.js
@@ -0,0 +1,6 @@
+// eslint-disable-next-line ava/no-ignored-test-files
+const test = require('ava');
+
+test('test', t => {
+ t.pass();
+});
diff --git a/test/config/fixtures/pkg-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-4.js b/test/config/fixtures/pkg-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-4.js
new file mode 100644
index 000000000..159662d3d
--- /dev/null
+++ b/test/config/fixtures/pkg-with-tests/dir-a-wrapper/dir-a/dir-a-wrapper-4.js
@@ -0,0 +1,6 @@
+// eslint-disable-next-line ava/no-ignored-test-files
+const test = require('ava');
+
+test('test', t => {
+ t.pass();
+});
diff --git a/test/config/fixtures/pkg-with-tests/dir-a/dir-a-base-1.js b/test/config/fixtures/pkg-with-tests/dir-a/dir-a-base-1.js
new file mode 100644
index 000000000..5ca41efa1
--- /dev/null
+++ b/test/config/fixtures/pkg-with-tests/dir-a/dir-a-base-1.js
@@ -0,0 +1,5 @@
+const test = require('ava');
+
+test('test', t => {
+ t.pass();
+});
diff --git a/test/config/fixtures/pkg-with-tests/dir-a/dir-a-base-2.js b/test/config/fixtures/pkg-with-tests/dir-a/dir-a-base-2.js
new file mode 100644
index 000000000..5ca41efa1
--- /dev/null
+++ b/test/config/fixtures/pkg-with-tests/dir-a/dir-a-base-2.js
@@ -0,0 +1,5 @@
+const test = require('ava');
+
+test('test', t => {
+ t.pass();
+});
diff --git a/test/config/fixtures/resolve-pkg-dir/package.json b/test/config/fixtures/pkg-with-tests/package.json
similarity index 67%
rename from test/config/fixtures/resolve-pkg-dir/package.json
rename to test/config/fixtures/pkg-with-tests/package.json
index 4cc2f3b9c..a1c131239 100644
--- a/test/config/fixtures/resolve-pkg-dir/package.json
+++ b/test/config/fixtures/pkg-with-tests/package.json
@@ -2,6 +2,6 @@
"name": "application-name",
"version": "0.0.1",
"ava": {
- "files": ["dir-a/*.js"]
+ "files": ["dir-a/*.js"]
}
- }
+}
diff --git a/test/config/fixtures/promise-config/ava.config.js b/test/config/fixtures/promise-config/ava.config.js
new file mode 100644
index 000000000..39bb4191e
--- /dev/null
+++ b/test/config/fixtures/promise-config/ava.config.js
@@ -0,0 +1,6 @@
+module.exports = Promise.resolve({
+ nonSemVerExperiments: {
+ nextGenConfig: true
+ },
+ failFast: true
+});
diff --git a/test/config/fixtures/promise-config/package.json b/test/config/fixtures/promise-config/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/config/fixtures/promise-config/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/config/test.js b/test/config/integration.js
similarity index 70%
rename from test/config/test.js
rename to test/config/integration.js
index 19528e003..4190f0195 100644
--- a/test/config/test.js
+++ b/test/config/integration.js
@@ -20,9 +20,9 @@ test('formats errors from ava.config.js', async t => {
t.regex(lines[4], /foo/);
});
-test('pkg-conf(resolve-dir): works as expected when run from the package.json directory', async t => {
+test('works as expected when run from the package.json directory', async t => {
const options = {
- cwd: exec.cwd('resolve-pkg-dir')
+ cwd: exec.cwd('pkg-with-tests')
};
const result = await exec.fixture([], options);
@@ -30,9 +30,9 @@ test('pkg-conf(resolve-dir): works as expected when run from the package.json di
t.snapshot(result.stats.passed, 'resolves test files from configuration');
});
-test('pkg-conf(resolve-dir): resolves tests from the package.json dir if none are specified on cli', async t => {
+test('resolves tests from the package.json dir if none are specified on cli', async t => {
const options = {
- cwd: exec.cwd('resolve-pkg-dir/dir-a-wrapper')
+ cwd: exec.cwd('pkg-with-tests/dir-a-wrapper')
};
const result = await exec.fixture(['--verbose'], options);
@@ -40,6 +40,18 @@ test('pkg-conf(resolve-dir): resolves tests from the package.json dir if none ar
t.snapshot(result.stats.passed, 'resolves test files from configuration');
});
+if (process.versions.node >= '12.17.0') {
+ test('resolves tests from an .mjs config file', async t => {
+ const options = {
+ cwd: exec.cwd('mjs-with-tests/dir-a-wrapper')
+ };
+
+ const result = await exec.fixture(['--verbose'], options);
+
+ t.snapshot(result.stats.passed, 'resolves test files from configuration');
+ });
+}
+
test('use current working directory if `package.json` is not found', async t => {
const cwd = tempy.directory();
const testFilePath = path.join(cwd, 'test.js');
diff --git a/test/config/loader.js b/test/config/loader.js
new file mode 100644
index 000000000..ce4164a90
--- /dev/null
+++ b/test/config/loader.js
@@ -0,0 +1,123 @@
+const path = require('path');
+const test = require('@ava/test');
+const {loadConfig} = require('../../lib/load-config');
+
+const CWD = process.cwd();
+const FIXTURE_ROOT = path.resolve(__dirname, '../../test-tap/fixture/load-config');
+
+const resolve = relpath => path.resolve(FIXTURE_ROOT, relpath);
+
+const loadFromSetup = setup => {
+ if (typeof setup === 'string') {
+ return loadConfig();
+ }
+
+ const {configFile, defaults, resolveFrom} = setup;
+ return loadConfig({configFile, defaults, resolveFrom});
+};
+
+const ok = setup => async (t, assert = tt => tt.pass()) => {
+ const fixture = typeof setup === 'string' ? setup : setup.fixture;
+
+ t.teardown(() => process.chdir(CWD));
+ process.chdir(resolve(fixture));
+
+ const conf = loadFromSetup(setup);
+ await t.notThrowsAsync(conf);
+ const result = await t.try(assert, await conf, setup);
+ result.commit();
+};
+
+const notOk = setup => async (t, assert = (tt, error) => tt.snapshot(error.message, 'error message')) => {
+ const fixture = typeof setup === 'string' ? setup : setup.fixture;
+
+ t.teardown(() => process.chdir(CWD));
+ process.chdir(resolve(fixture));
+
+ const conf = loadFromSetup(setup);
+ const error = await t.throwsAsync(conf);
+ const result = await t.try(assert, error, setup);
+ result.commit();
+};
+
+test.serial('finds config in package.json', ok('package-only'), (t, conf) => {
+ t.true(conf.failFast);
+});
+
+test.serial('loads config from a particular directory', ok({
+ fixture: 'throws',
+ resolveFrom: resolve('package-only')
+}), (t, conf) => {
+ t.true(conf.failFast);
+});
+
+test.serial('throws an error if both configs are present', notOk('package-yes-file-yes'));
+
+test.serial('explicit configFile option overrides package.json config', ok({
+ fixture: 'package-yes-explicit-yes',
+ configFile: 'explicit.js'
+}), (t, conf) => {
+ t.is(conf.files, 'package-yes-explicit-yes-test-value');
+});
+
+test.serial('throws if configFile option is not in the same directory as the package.json file', notOk({
+ fixture: 'package-yes-explicit-yes',
+ configFile: 'nested/explicit.js'
+}));
+
+test.serial('throws if configFile option has an unsupported extension', notOk({
+ fixture: 'explicit-bad-extension',
+ configFile: 'explicit.txt'
+}));
+
+test.serial('merges in defaults passed with initial call', ok({
+ fixture: 'package-only',
+ defaults: {
+ files: ['123', '!456']
+ }
+}), (t, conf, {defaults}) => {
+ t.true(conf.failFast, 'preserves original props');
+ t.is(conf.files, defaults.files, 'merges in extra props');
+});
+
+test.serial('loads config from file with `export default` syntax', ok('package-no-file-yes'), (t, conf) => {
+ t.is(conf.files, 'config-file-esm-test-value');
+});
+
+test.serial('loads config from factory function', ok('package-no-file-yes-factory'), (t, conf) => {
+ t.assert(conf.files.startsWith(FIXTURE_ROOT));
+});
+
+test.serial('does not support require() inside config.js files', notOk('require'));
+
+test.serial('throws an error if a config factory returns a promise', notOk('factory-no-promise-return'));
+
+test.serial('throws an error if a config exports a promise', notOk('no-promise-config'));
+
+test.serial('throws an error if a config factory does not return a plain object', notOk('factory-no-plain-return'));
+
+test.serial('throws an error if a config does not export a plain object', notOk('no-plain-config'));
+
+test.serial('receives a `projectDir` property', ok('package-only'), (t, conf) => {
+ t.assert(conf.projectDir.startsWith(FIXTURE_ROOT));
+});
+
+test.serial('rethrows wrapped module errors', notOk('throws'), (t, error) => {
+ t.is(error.parent.message, 'foo');
+});
+
+test.serial('throws an error if a .js config file has no default export', notOk('no-default-export'));
+
+test.serial('throws an error if a config file contains `ava` property', notOk('contains-ava-property'));
+
+test.serial('throws an error if a config file contains a non-object `nonSemVerExperiments` property', notOk('non-object-experiments'));
+
+test.serial('throws an error if a config file enables an unsupported experiment', notOk('unsupported-experiments'));
+
+test.serial('loads .cjs config', ok('cjs'), (t, conf) => {
+ t.assert(conf.files.startsWith(FIXTURE_ROOT));
+});
+
+test.serial('throws an error if both .js and .cjs configs are present', notOk('file-yes-cjs-yes'));
+
+test.serial('refuses to load .mjs config', notOk('mjs'));
diff --git a/test/config/next-gen.js b/test/config/next-gen.js
new file mode 100644
index 000000000..b1d49987c
--- /dev/null
+++ b/test/config/next-gen.js
@@ -0,0 +1,84 @@
+const path = require('path');
+const test = require('@ava/test');
+const {loadConfig} = require('../../lib/load-config');
+
+const CWD = process.cwd();
+const FIXTURE_ROOT = path.resolve(__dirname, 'fixtures');
+
+const resolve = relpath => path.resolve(FIXTURE_ROOT, relpath);
+
+const loadFromSetup = setup => {
+ if (typeof setup === 'string') {
+ return loadConfig();
+ }
+
+ const {configFile, defaults, resolveFrom} = setup;
+ return loadConfig({configFile, defaults, resolveFrom});
+};
+
+const ok = setup => async (t, assert = tt => tt.pass()) => {
+ const fixture = typeof setup === 'string' ? setup : setup.fixture;
+
+ t.teardown(() => process.chdir(CWD));
+ process.chdir(resolve(fixture));
+
+ const conf = loadFromSetup(setup);
+ await t.notThrowsAsync(conf);
+ const result = await t.try(assert, await conf, setup);
+ result.commit();
+};
+
+const notOk = setup => async (t, assert = (tt, error) => tt.snapshot(error.message, 'error message')) => {
+ const fixture = typeof setup === 'string' ? setup : setup.fixture;
+
+ t.teardown(() => process.chdir(CWD));
+ process.chdir(resolve(fixture));
+
+ const conf = loadFromSetup(setup);
+ const error = await t.throwsAsync(conf);
+ const result = await t.try(assert, error, setup);
+ result.commit();
+};
+
+test.serial('loads .mjs config', ok('mjs'), (t, conf) => {
+ t.true(conf.failFast);
+});
+
+test.serial('handles errors when loading .mjs config', notOk({
+ fixture: 'mjs',
+ configFile: 'error.mjs'
+}));
+
+test.serial('fails when .mjs config does not have a default export', notOk({
+ fixture: 'mjs',
+ configFile: 'no-default-export.mjs'
+}));
+
+test.serial('loads .js config as CommonJS', ok('js-as-cjs'), (t, conf) => {
+ t.true(conf.failFast);
+});
+
+test.serial('loads .js config as ESM', ok('js-as-esm'), (t, conf) => {
+ t.true(conf.failFast);
+});
+
+test.serial('handles errors when loading .js config as ESM', notOk({
+ fixture: 'js-as-esm',
+ configFile: 'error.js'
+}));
+
+test.serial('fails when .js config does not have a default export', notOk({
+ fixture: 'js-as-esm',
+ configFile: 'no-default-export.js'
+}));
+
+test.serial('throws an error if .js, .cjs and .mjs configs are present', notOk('file-yes-cjs-yes-mjs-yes'));
+
+test.serial('config factory returns a promise', ok('factory-promise-return'), (t, conf) => {
+ t.true(conf.failFast);
+});
+
+test.serial('config exports a promise', ok('promise-config'), (t, conf) => {
+ t.true(conf.failFast);
+});
+
diff --git a/test/config/snapshots/test.js.md b/test/config/snapshots/integration.js.md
similarity index 56%
rename from test/config/snapshots/test.js.md
rename to test/config/snapshots/integration.js.md
index 4115fcb77..7ee552098 100644
--- a/test/config/snapshots/test.js.md
+++ b/test/config/snapshots/integration.js.md
@@ -1,10 +1,25 @@
-# Snapshot report for `test/config/test.js`
+# Snapshot report for `test/config/integration.js`
-The actual snapshot is saved in `test.js.snap`.
+The actual snapshot is saved in `integration.js.snap`.
Generated by [AVA](https://avajs.dev).
-## pkg-conf(resolve-dir): resolves tests from the package.json dir if none are specified on cli
+## works as expected when run from the package.json directory
+
+> resolves test files from configuration
+
+ [
+ {
+ file: 'dir-a/dir-a-base-1.js',
+ title: 'test',
+ },
+ {
+ file: 'dir-a/dir-a-base-2.js',
+ title: 'test',
+ },
+ ]
+
+## resolves tests from the package.json dir if none are specified on cli
> resolves test files from configuration
@@ -19,17 +34,17 @@ Generated by [AVA](https://avajs.dev).
},
]
-## pkg-conf(resolve-dir): works as expected when run from the package.json directory
+## resolves tests from an .mjs config file
> resolves test files from configuration
[
{
- file: 'dir-a/dir-a-base-1.js',
+ file: '../dir-a/dir-a-base-1.js',
title: 'test',
},
{
- file: 'dir-a/dir-a-base-2.js',
+ file: '../dir-a/dir-a-base-2.js',
title: 'test',
},
]
diff --git a/test/config/snapshots/integration.js.snap b/test/config/snapshots/integration.js.snap
new file mode 100644
index 000000000..8bc49cba6
Binary files /dev/null and b/test/config/snapshots/integration.js.snap differ
diff --git a/test/config/snapshots/loader.js.md b/test/config/snapshots/loader.js.md
new file mode 100644
index 000000000..65fa4e11b
--- /dev/null
+++ b/test/config/snapshots/loader.js.md
@@ -0,0 +1,89 @@
+# Snapshot report for `test/config/loader.js`
+
+The actual snapshot is saved in `loader.js.snap`.
+
+Generated by [AVA](https://avajs.dev).
+
+## throws an error if both configs are present
+
+> error message
+
+ 'Conflicting configuration in ava.config.js and package.json'
+
+## throws if configFile option is not in the same directory as the package.json file
+
+> error message
+
+ 'Config files must be located next to the package.json file'
+
+## throws if configFile option has an unsupported extension
+
+> error message
+
+ 'Config files must have .js, .cjs or .mjs extensions'
+
+## does not support require() inside config.js files
+
+> error message
+
+ 'Error loading ava.config.js: require is not defined'
+
+## throws an error if a config factory returns a promise
+
+> error message
+
+ 'ava.config.js exported a promise or an asynchronous factory function. You must enable the ’asyncConfigurationLoading’ experiment for this to work.'
+
+## throws an error if a config exports a promise
+
+> error message
+
+ 'ava.config.js must export a plain object or factory function'
+
+## throws an error if a config factory does not return a plain object
+
+> error message
+
+ 'Factory method exported by ava.config.js must return a plain object'
+
+## throws an error if a config does not export a plain object
+
+> error message
+
+ 'ava.config.js must export a plain object or factory function'
+
+## throws an error if a .js config file has no default export
+
+> error message
+
+ 'ava.config.js must have a default export, using ES module syntax'
+
+## throws an error if a config file contains `ava` property
+
+> error message
+
+ 'Encountered ’ava’ property in ava.config.js; avoid wrapping the configuration'
+
+## throws an error if a config file contains a non-object `nonSemVerExperiments` property
+
+> error message
+
+ 'nonSemVerExperiments from ava.config.js must be an object'
+
+## throws an error if a config file enables an unsupported experiment
+
+> error message
+
+ 'nonSemVerExperiments.unsupported from ava.config.js is not a supported experiment'
+
+## throws an error if both .js and .cjs configs are present
+
+> error message
+
+ 'Conflicting configuration in ava.config.js and ava.config.cjs'
+
+## refuses to load .mjs config
+
+> error message
+
+ 'AVA cannot yet load ava.config.mjs files'
diff --git a/test/config/snapshots/loader.js.snap b/test/config/snapshots/loader.js.snap
new file mode 100644
index 000000000..8c2da2fb3
Binary files /dev/null and b/test/config/snapshots/loader.js.snap differ
diff --git a/test/config/snapshots/next-gen.js.md b/test/config/snapshots/next-gen.js.md
new file mode 100644
index 000000000..5a81d52e7
--- /dev/null
+++ b/test/config/snapshots/next-gen.js.md
@@ -0,0 +1,35 @@
+# Snapshot report for `test/config/next-gen.js`
+
+The actual snapshot is saved in `next-gen.js.snap`.
+
+Generated by [AVA](https://avajs.dev).
+
+## handles errors when loading .mjs config
+
+> error message
+
+ 'Error loading error.mjs: 🙈'
+
+## fails when .mjs config does not have a default export
+
+> error message
+
+ 'no-default-export.mjs must have a default export'
+
+## handles errors when loading .js config as ESM
+
+> error message
+
+ 'Error loading error.js: 🙈'
+
+## fails when .js config does not have a default export
+
+> error message
+
+ 'no-default-export.js must have a default export'
+
+## throws an error if .js, .cjs and .mjs configs are present
+
+> error message
+
+ 'Conflicting configuration in ava.config.js and ava.config.cjs & ava.config.mjs'
diff --git a/test/config/snapshots/next-gen.js.snap b/test/config/snapshots/next-gen.js.snap
new file mode 100644
index 000000000..ed9513345
Binary files /dev/null and b/test/config/snapshots/next-gen.js.snap differ
diff --git a/test/config/snapshots/test.js.snap b/test/config/snapshots/test.js.snap
deleted file mode 100644
index 4c31532fe..000000000
Binary files a/test/config/snapshots/test.js.snap and /dev/null differ
diff --git a/test/configurable-module-format/snapshots/invalid-configurations.js.md b/test/configurable-module-format/snapshots/invalid-configurations.js.md
index 61c38084e..66ed27328 100644
--- a/test/configurable-module-format/snapshots/invalid-configurations.js.md
+++ b/test/configurable-module-format/snapshots/invalid-configurations.js.md
@@ -4,13 +4,13 @@ The actual snapshot is saved in `invalid-configurations.js.snap`.
Generated by [AVA](https://avajs.dev).
-## cannot configure how cjs extensions should be loaded
+## cannot configure how js extensions should be loaded
> Snapshot 1
'When specifying module types, use `true` for ’cjs’, ’mjs’ and ’js’ extensions'
-## cannot configure how js extensions should be loaded
+## cannot configure how cjs extensions should be loaded
> Snapshot 1
diff --git a/test/configurable-module-format/snapshots/invalid-configurations.js.snap b/test/configurable-module-format/snapshots/invalid-configurations.js.snap
index a26ad210b..ade5d8a99 100644
Binary files a/test/configurable-module-format/snapshots/invalid-configurations.js.snap and b/test/configurable-module-format/snapshots/invalid-configurations.js.snap differ
diff --git a/test/environment-variables/snapshots/test.js.md b/test/environment-variables/snapshots/test.js.md
index 138d60426..24adf63eb 100644
--- a/test/environment-variables/snapshots/test.js.md
+++ b/test/environment-variables/snapshots/test.js.md
@@ -4,13 +4,7 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## errors if environment variables are not string values
-
-> fails with message
-
- 'The ’environmentVariables’ configuration must be an object containing string values.'
-
-## overrides environment variables provided through the CLI
+## sets default environment variables from the config
> tests pass
@@ -21,7 +15,7 @@ Generated by [AVA](https://avajs.dev).
},
]
-## sets default environment variables from the config
+## overrides environment variables provided through the CLI
> tests pass
@@ -31,3 +25,9 @@ Generated by [AVA](https://avajs.dev).
title: 'works',
},
]
+
+## errors if environment variables are not string values
+
+> fails with message
+
+ 'The ’environmentVariables’ configuration must be an object containing string values.'
diff --git a/test/environment-variables/snapshots/test.js.snap b/test/environment-variables/snapshots/test.js.snap
index 43f12daba..8f554a531 100644
Binary files a/test/environment-variables/snapshots/test.js.snap and b/test/environment-variables/snapshots/test.js.snap differ
diff --git a/test/extensions/snapshots/test.js.md b/test/extensions/snapshots/test.js.md
index 693d6a568..9be4b84d8 100644
--- a/test/extensions/snapshots/test.js.md
+++ b/test/extensions/snapshots/test.js.md
@@ -4,14 +4,14 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## errors if top-level and babel extensions include duplicates
+## errors if top-level extensions include duplicates
> fails with message
- 'Unexpected duplicate extensions in options: ’jsx’.'
+ 'Unexpected duplicate extensions in options: ’js’, ’jsx’.'
-## errors if top-level extensions include duplicates
+## errors if top-level and babel extensions include duplicates
> fails with message
- 'Unexpected duplicate extensions in options: ’js’, ’jsx’.'
+ 'Unexpected duplicate extensions in options: ’jsx’.'
diff --git a/test/extensions/snapshots/test.js.snap b/test/extensions/snapshots/test.js.snap
index 58e5b89be..eda6f053d 100644
Binary files a/test/extensions/snapshots/test.js.snap and b/test/extensions/snapshots/test.js.snap differ
diff --git a/test/hook-restrictions/snapshots/test.js.md b/test/hook-restrictions/snapshots/test.js.md
index 1eb6c2fe2..0f6c5f4bb 100644
--- a/test/hook-restrictions/snapshots/test.js.md
+++ b/test/hook-restrictions/snapshots/test.js.md
@@ -4,14 +4,14 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## `t.try()` cannot be used in hooks
+## snapshots cannot be used in hooks
> error message
- '`t.try()` can only be used in tests'
+ '`t.snapshot()` can only be used in tests'
-## snapshots cannot be used in hooks
+## `t.try()` cannot be used in hooks
> error message
- '`t.snapshot()` can only be used in tests'
+ '`t.try()` can only be used in tests'
diff --git a/test/line-numbers/snapshots/test.js.md b/test/line-numbers/snapshots/test.js.md
index eff67de3a..272fafb5e 100644
--- a/test/line-numbers/snapshots/test.js.md
+++ b/test/line-numbers/snapshots/test.js.md
@@ -4,7 +4,7 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## nested call is selected
+## select test by line number
> no todo tests are selected
@@ -15,23 +15,11 @@ Generated by [AVA](https://avajs.dev).
[
{
file: 'line-numbers.js',
- title: 'nested call',
+ title: 'unicorn',
},
]
-## no test selected by line number
-
-> fails with message
-
- 'Line numbers for line-numbers.js did not match any tests'
-
-## parent call is not selected
-
-> fails with message
-
- 'Line numbers for line-numbers.js did not match any tests'
-
-## select only one of two tests declared on same line
+## select serial test by line number
> no todo tests are selected
@@ -42,26 +30,22 @@ Generated by [AVA](https://avajs.dev).
[
{
file: 'line-numbers.js',
- title: 'moon',
+ title: 'cat',
},
]
-## select serial test by line number
-
-> no todo tests are selected
-
- []
+## select todo test by line number
-> selected tests pass
+> selected todo test passes
[
{
file: 'line-numbers.js',
- title: 'cat',
+ title: 'dog',
},
]
-## select test by line number
+## select tests by line number range
> no todo tests are selected
@@ -70,13 +54,17 @@ Generated by [AVA](https://avajs.dev).
> selected tests pass
[
+ {
+ file: 'line-numbers.js',
+ title: 'rainbow',
+ },
{
file: 'line-numbers.js',
title: 'unicorn',
},
]
-## select tests by line number range
+## select two tests declared on same line
> no todo tests are selected
@@ -87,26 +75,42 @@ Generated by [AVA](https://avajs.dev).
[
{
file: 'line-numbers.js',
- title: 'rainbow',
+ title: 'moon',
},
{
file: 'line-numbers.js',
- title: 'unicorn',
+ title: 'sun',
},
]
-## select todo test by line number
+## select only one of two tests declared on same line
-> selected todo test passes
+> no todo tests are selected
+
+ []
+
+> selected tests pass
[
{
file: 'line-numbers.js',
- title: 'dog',
+ title: 'moon',
},
]
-## select two tests declared on same line
+## no test selected by line number
+
+> fails with message
+
+ 'Line numbers for line-numbers.js did not match any tests'
+
+## parent call is not selected
+
+> fails with message
+
+ 'Line numbers for line-numbers.js did not match any tests'
+
+## nested call is selected
> no todo tests are selected
@@ -117,10 +121,6 @@ Generated by [AVA](https://avajs.dev).
[
{
file: 'line-numbers.js',
- title: 'moon',
- },
- {
- file: 'line-numbers.js',
- title: 'sun',
+ title: 'nested call',
},
]
diff --git a/test/line-numbers/snapshots/test.js.snap b/test/line-numbers/snapshots/test.js.snap
index 4ed4624c9..1f428b16d 100644
Binary files a/test/line-numbers/snapshots/test.js.snap and b/test/line-numbers/snapshots/test.js.snap differ
diff --git a/test/node-arguments/snapshots/test.js.md b/test/node-arguments/snapshots/test.js.md
index b44239fd0..9817e5a1f 100644
--- a/test/node-arguments/snapshots/test.js.md
+++ b/test/node-arguments/snapshots/test.js.md
@@ -4,12 +4,6 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## detects incomplete --node-arguments
-
-> fails with message
-
- 'Could not parse `--node-arguments` value. Make sure all strings are closed and backslashes are used correctly.'
-
## passed node arguments to workers
> tests pass
@@ -21,6 +15,12 @@ Generated by [AVA](https://avajs.dev).
},
]
+## detects incomplete --node-arguments
+
+> fails with message
+
+ 'Could not parse `--node-arguments` value. Make sure all strings are closed and backslashes are used correctly.'
+
## reads node arguments from config
> tests pass
diff --git a/test/node-arguments/snapshots/test.js.snap b/test/node-arguments/snapshots/test.js.snap
index 1e47c193a..ac31a5473 100644
Binary files a/test/node-arguments/snapshots/test.js.snap and b/test/node-arguments/snapshots/test.js.snap differ
diff --git a/test/shared-workers/unsupported-protocol/snapshots/test.js.md b/test/shared-workers/unsupported-protocol/snapshots/test.js.md
index c3ce2a63b..c3b71a67e 100644
--- a/test/shared-workers/unsupported-protocol/snapshots/test.js.md
+++ b/test/shared-workers/unsupported-protocol/snapshots/test.js.md
@@ -4,14 +4,14 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## must negotiate a supported protocol in the shared worker
+## must negotiate a supported protocol in the test worker
> Snapshot 1
- 'This version of AVA (VERSION) is not compatible with shared worker plugin at FILE'
+ 'This version of AVA (VERSION) does not support any of the desired shared worker protocols: 🙈'
-## must negotiate a supported protocol in the test worker
+## must negotiate a supported protocol in the shared worker
> Snapshot 1
- 'This version of AVA (VERSION) does not support any of the desired shared worker protocols: 🙈'
+ 'This version of AVA (VERSION) is not compatible with shared worker plugin at FILE'
diff --git a/test/shared-workers/unsupported-protocol/snapshots/test.js.snap b/test/shared-workers/unsupported-protocol/snapshots/test.js.snap
index b47ac99b1..49b269cfe 100644
Binary files a/test/shared-workers/unsupported-protocol/snapshots/test.js.snap and b/test/shared-workers/unsupported-protocol/snapshots/test.js.snap differ
diff --git a/test/snapshot-order/snapshots/randomness.js.md b/test/snapshot-order/snapshots/randomness.js.md
index 14016b0e8..bc4cf91b2 100644
--- a/test/snapshot-order/snapshots/randomness.js.md
+++ b/test/snapshot-order/snapshots/randomness.js.md
@@ -6,7 +6,7 @@ Generated by [AVA](https://avajs.dev).
## deterministic and sorted over a large, random test case
-> Snapshot 1
+> resulting snapshot in binary encoding
Buffer @Uint8Array [
41564120 536e6170 73686f74 2076320a 020019c4 186451f5 248fc7d2 9bc1c0e4
diff --git a/test/snapshot-removal/fixtures/fixed-snapshot-dir/package.json b/test/snapshot-removal/fixtures/fixed-snapshot-dir/package.json
new file mode 100644
index 000000000..6aa55350f
--- /dev/null
+++ b/test/snapshot-removal/fixtures/fixed-snapshot-dir/package.json
@@ -0,0 +1,5 @@
+{
+ "ava": {
+ "snapshotDir": "fixedSnapshotDir"
+ }
+}
diff --git a/test/snapshot-removal/fixtures/fixed-snapshot-dir/test.js b/test/snapshot-removal/fixtures/fixed-snapshot-dir/test.js
new file mode 100644
index 000000000..61e035eae
--- /dev/null
+++ b/test/snapshot-removal/fixtures/fixed-snapshot-dir/test.js
@@ -0,0 +1,22 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('some snapshots', t => {
+ t.snapshot('foo');
+ t.snapshot('bar');
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.snapshot('baz');
+ t.pass();
+ });
+} else {
+ test('some snapshots', t => {
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/fixtures/no-snapshots/package.json b/test/snapshot-removal/fixtures/no-snapshots/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/no-snapshots/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/no-snapshots/test.js b/test/snapshot-removal/fixtures/no-snapshots/test.js
new file mode 100644
index 000000000..4f9782f12
--- /dev/null
+++ b/test/snapshot-removal/fixtures/no-snapshots/test.js
@@ -0,0 +1,5 @@
+const test = require('ava');
+
+test('without snapshots', t => {
+ t.pass();
+});
diff --git a/test/snapshot-removal/fixtures/only-test/package.json b/test/snapshot-removal/fixtures/only-test/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/only-test/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/only-test/test.js b/test/snapshot-removal/fixtures/only-test/test.js
new file mode 100644
index 000000000..0bad8f5f2
--- /dev/null
+++ b/test/snapshot-removal/fixtures/only-test/test.js
@@ -0,0 +1,22 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('some snapshots', t => {
+ t.snapshot('foo');
+ t.snapshot('bar');
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.snapshot('baz');
+ t.pass();
+ });
+} else {
+ test.only('some snapshots', t => {
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/fixtures/removal/package.json b/test/snapshot-removal/fixtures/removal/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/removal/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/removal/test.js b/test/snapshot-removal/fixtures/removal/test.js
new file mode 100644
index 000000000..61e035eae
--- /dev/null
+++ b/test/snapshot-removal/fixtures/removal/test.js
@@ -0,0 +1,22 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('some snapshots', t => {
+ t.snapshot('foo');
+ t.snapshot('bar');
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.snapshot('baz');
+ t.pass();
+ });
+} else {
+ test('some snapshots', t => {
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/fixtures/skipped-snapshots-in-try/package.json b/test/snapshot-removal/fixtures/skipped-snapshots-in-try/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/skipped-snapshots-in-try/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/skipped-snapshots-in-try/test.js b/test/snapshot-removal/fixtures/skipped-snapshots-in-try/test.js
new file mode 100644
index 000000000..cc43c7145
--- /dev/null
+++ b/test/snapshot-removal/fixtures/skipped-snapshots-in-try/test.js
@@ -0,0 +1,23 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('skipped snapshots in try', async t => {
+ const attempt = await t.try(tt => {
+ tt.snapshot('in try');
+ });
+
+ attempt.commit();
+
+ t.pass();
+ });
+} else {
+ test('skipped snapshots in try', async t => {
+ const attempt = await t.try(tt => {
+ tt.snapshot.skip('in try');
+ });
+
+ attempt.discard();
+
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/fixtures/skipped-snapshots/package.json b/test/snapshot-removal/fixtures/skipped-snapshots/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/skipped-snapshots/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/skipped-snapshots/test.js b/test/snapshot-removal/fixtures/skipped-snapshots/test.js
new file mode 100644
index 000000000..a01ab31fe
--- /dev/null
+++ b/test/snapshot-removal/fixtures/skipped-snapshots/test.js
@@ -0,0 +1,23 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('some snapshots', t => {
+ t.snapshot('foo');
+ t.snapshot('bar');
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.snapshot('baz');
+ t.pass();
+ });
+} else {
+ test('some snapshots', t => {
+ t.snapshot.skip('foo');
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/fixtures/skipped-tests/package.json b/test/snapshot-removal/fixtures/skipped-tests/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/skipped-tests/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/skipped-tests/test.js b/test/snapshot-removal/fixtures/skipped-tests/test.js
new file mode 100644
index 000000000..a4344b841
--- /dev/null
+++ b/test/snapshot-removal/fixtures/skipped-tests/test.js
@@ -0,0 +1,22 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('some snapshots', t => {
+ t.snapshot('foo');
+ t.snapshot('bar');
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.snapshot('baz');
+ t.pass();
+ });
+} else {
+ test.skip('some snapshots', t => {
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/fixtures/snapshot-dir/package.json b/test/snapshot-removal/fixtures/snapshot-dir/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/snapshot-dir/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/snapshot-dir/test/test.js b/test/snapshot-removal/fixtures/snapshot-dir/test/test.js
new file mode 100644
index 000000000..61e035eae
--- /dev/null
+++ b/test/snapshot-removal/fixtures/snapshot-dir/test/test.js
@@ -0,0 +1,22 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('some snapshots', t => {
+ t.snapshot('foo');
+ t.snapshot('bar');
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.snapshot('baz');
+ t.pass();
+ });
+} else {
+ test('some snapshots', t => {
+ t.pass();
+ });
+
+ test('another snapshot', t => {
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/fixtures/try/package.json b/test/snapshot-removal/fixtures/try/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/test/snapshot-removal/fixtures/try/package.json
@@ -0,0 +1 @@
+{}
diff --git a/test/snapshot-removal/fixtures/try/test.js b/test/snapshot-removal/fixtures/try/test.js
new file mode 100644
index 000000000..fb4d44277
--- /dev/null
+++ b/test/snapshot-removal/fixtures/try/test.js
@@ -0,0 +1,23 @@
+const test = require(process.env.AVA_PATH); // This fixture is copied to a temporary directory, so require AVA through its configured path.
+
+if (process.env.TEMPLATE) {
+ test('snapshots in try', async t => {
+ const attempt = await t.try(tt => {
+ tt.snapshot('in try');
+ });
+
+ attempt.commit();
+
+ t.pass();
+ });
+} else {
+ test('snapshots in try', async t => {
+ const attempt = await t.try(tt => {
+ tt.snapshot('in try');
+ });
+
+ attempt.discard();
+
+ t.pass();
+ });
+}
diff --git a/test/snapshot-removal/helpers/macros.js b/test/snapshot-removal/helpers/macros.js
new file mode 100644
index 000000000..35d4a42b5
--- /dev/null
+++ b/test/snapshot-removal/helpers/macros.js
@@ -0,0 +1,86 @@
+const fs = require('fs').promises;
+const exec = require('../../helpers/exec');
+const path = require('path');
+const tempy = require('tempy');
+const fse = require('fs-extra');
+
+function withTemporaryFixture(macro) {
+ const avaPath = path.resolve(path.join(__dirname, '..', '..', '..'));
+
+ return async (t, {cwd, env, ...options}) => {
+ await tempy.directory.task(async temporary => {
+ await fse.copy(cwd, temporary);
+ await macro(t, {
+ cwd: temporary,
+ env: {
+ AVA_PATH: avaPath,
+ ...env
+ },
+ ...options
+ });
+ });
+ };
+}
+
+module.exports.withTemporaryFixture = withTemporaryFixture;
+
+async function testSnapshotPruning(t, {
+ cwd,
+ env,
+ cli,
+ remove,
+ snapshotPath = 'test.js.snap',
+ reportPath = 'test.js.md',
+ checkRun = async (t, run) => {
+ await t.notThrowsAsync(run, 'Expected fixture not to throw');
+ }
+}) {
+ snapshotPath = path.join(cwd, snapshotPath);
+ reportPath = path.join(cwd, reportPath);
+
+ t.teardown(async () => {
+ try {
+ await fs.unlink(snapshotPath);
+ await fs.unlink(reportPath);
+ } catch {}
+ });
+
+ // Execute fixture as template to generate snapshots
+ const templateResult = exec.fixture(['--update-snapshots'], {
+ cwd,
+ env: {
+ ...env,
+ AVA_FORCE_CI: 'not-ci',
+ TEMPLATE: 'true'
+ }
+ });
+
+ await t.notThrowsAsync(templateResult, 'Template crashed - there\'s a bug in the test');
+
+ // Check that the snapshots were created
+ await t.notThrowsAsync(fs.access(snapshotPath), 'Template didn\'t create a snapshot - there\'s a bug in the test');
+ await t.notThrowsAsync(fs.access(reportPath), 'Template didn\'t create a report - there\'s a bug in the test');
+
+ // Execute fixture as run
+ const run = exec.fixture(cli, {
+ cwd,
+ env: {
+ AVA_FORCE_CI: 'not-ci',
+ ...env
+ }
+ });
+
+ await checkRun(t, run);
+
+ if (remove) {
+ // Assert files don't exist
+ await t.throwsAsync(fs.access(snapshotPath), {code: 'ENOENT'}, 'Expected snapshot to be removed');
+ await t.throwsAsync(fs.access(reportPath), {code: 'ENOENT'}, 'Expected report to be remove');
+ } else {
+ // Assert files exist
+ await t.notThrowsAsync(fs.access(snapshotPath), 'Expected snapshot not to be removed');
+ await t.notThrowsAsync(fs.access(reportPath), 'Expected report not to be removed');
+ }
+}
+
+module.exports.testSnapshotPruning = testSnapshotPruning;
diff --git a/test/snapshot-removal/snapshots/test.js.md b/test/snapshot-removal/snapshots/test.js.md
new file mode 100644
index 000000000..17be3725f
--- /dev/null
+++ b/test/snapshot-removal/snapshots/test.js.md
@@ -0,0 +1,76 @@
+# Snapshot report for `test/snapshot-removal/test.js`
+
+The actual snapshot is saved in `test.js.snap`.
+
+Generated by [AVA](https://avajs.dev).
+
+## snapshots remain if they are still used
+
+> passed tests
+
+ [
+ {
+ file: 'test.js',
+ title: 'another snapshot',
+ },
+ {
+ file: 'test.js',
+ title: 'some snapshots',
+ },
+ ]
+
+> files where snapshots could not be updated
+
+ []
+
+## snapshots remain if tests run with --match
+
+> stderr
+
+ 'Snapshots cannot be updated when matching specific tests.'
+
+## snapshots remain if tests selected by line numbers
+
+> stderr
+
+ 'Snapshots cannot be updated when selecting specific tests by their line number.'
+
+## snapshots remain if using test.only
+
+> files where snapshots could not be updated
+
+ [
+ {
+ file: 'test.js',
+ },
+ ]
+
+## snapshots remain if tests are skipped
+
+> files where snapshots could not be updated
+
+ [
+ {
+ file: 'test.js',
+ },
+ ]
+
+## snapshots remain if snapshot assertions are skipped
+
+> files where snapshots could not be updated
+
+ [
+ {
+ file: 'test.js',
+ },
+ ]
+
+## snapshots remain if skipped in a discarded try()
+
+> files where snapshots could not be updated
+
+ [
+ {
+ file: 'test.js',
+ },
+ ]
diff --git a/test/snapshot-removal/snapshots/test.js.snap b/test/snapshot-removal/snapshots/test.js.snap
new file mode 100644
index 000000000..4734fb9c1
Binary files /dev/null and b/test/snapshot-removal/snapshots/test.js.snap differ
diff --git a/test/snapshot-removal/test.js b/test/snapshot-removal/test.js
new file mode 100644
index 000000000..8f7f472a2
--- /dev/null
+++ b/test/snapshot-removal/test.js
@@ -0,0 +1,133 @@
+const test = require('@ava/test');
+const exec = require('../helpers/exec');
+const {testSnapshotPruning, withTemporaryFixture} = require('./helpers/macros');
+const path = require('path');
+
+const macro = withTemporaryFixture(testSnapshotPruning);
+
+test('snapshots are removed when tests stop using them', macro, {
+ cwd: exec.cwd('removal'),
+ cli: ['--update-snapshots'],
+ remove: true
+});
+
+test('snapshots are removed from a snapshot directory', macro, {
+ cwd: exec.cwd('snapshot-dir'),
+ cli: ['--update-snapshots'],
+ remove: true,
+ snapshotPath: path.join('test', 'snapshots', 'test.js.snap'),
+ reportPath: path.join('test', 'snapshots', 'test.js.md')
+});
+
+test('snapshots are removed from a custom snapshotDir', macro, {
+ cwd: exec.cwd('fixed-snapshot-dir'),
+ cli: ['--update-snapshots'],
+ remove: true,
+ snapshotPath: path.join('fixedSnapshotDir', 'test.js.snap'),
+ reportPath: path.join('fixedSnapshotDir', 'test.js.md')
+});
+
+test('removing non-existent snapshots doesn\'t throw', async t => {
+ // Execute fixture; this should try to unlink the nonexistent snapshots, and
+ // should not throw
+ const run = exec.fixture(['--update-snapshots'], {
+ cwd: exec.cwd('no-snapshots'),
+ env: {
+ AVA_FORCE_CI: 'not-ci'
+ }
+ });
+
+ await t.notThrowsAsync(run);
+});
+
+test('snapshots remain if not updating', macro, {
+ cwd: exec.cwd('removal'),
+ cli: [],
+ remove: false
+});
+
+test('snapshots remain if they are still used', macro, {
+ cwd: exec.cwd('removal'),
+ cli: ['--update-snapshots'],
+ remove: false,
+ env: {
+ TEMPLATE: 'true'
+ },
+ async checkRun(t, run) {
+ await t.notThrowsAsync(run, 'Expected fixture not to throw');
+ const result = await run;
+ t.snapshot(result.stats.passed, 'passed tests');
+ t.snapshot(result.stats.unsavedSnapshots, 'files where snapshots could not be updated');
+ }
+});
+
+test('snapshots remain if tests run with --match', macro, {
+ cwd: exec.cwd('removal'),
+ cli: ['--update-snapshots', '--match=\'*snapshot*\''],
+ remove: false,
+ checkRun: async (t, run) => {
+ const result = await t.throwsAsync(run, undefined, 'Expected fixture to throw');
+ t.snapshot(exec.cleanOutput(result.stderr), 'stderr');
+ }
+});
+
+test('snapshots remain if tests selected by line numbers', macro, {
+ cwd: exec.cwd('removal'),
+ cli: ['test.js:3-12', '--update-snapshots'],
+ remove: false,
+ checkRun: async (t, run) => {
+ const result = await t.throwsAsync(run, undefined, 'Expected fixture to throw');
+ t.snapshot(exec.cleanOutput(result.stderr), 'stderr');
+ }
+});
+
+test('snapshots remain if using test.only', macro, {
+ cwd: exec.cwd('only-test'),
+ cli: ['--update-snapshots'],
+ remove: false,
+ checkRun: async (t, run) => {
+ await t.notThrowsAsync(run, 'Expected fixture not to throw');
+ const result = await run;
+ t.snapshot(result.stats.unsavedSnapshots, 'files where snapshots could not be updated');
+ }
+});
+
+test('snapshots remain if tests are skipped', macro, {
+ cwd: exec.cwd('skipped-tests'),
+ cli: ['--update-snapshots'],
+ remove: false,
+ checkRun: async (t, run) => {
+ await t.notThrowsAsync(run, 'Expected fixture not to throw');
+ const result = await run;
+ t.snapshot(result.stats.unsavedSnapshots, 'files where snapshots could not be updated');
+ }
+});
+
+test('snapshots remain if snapshot assertions are skipped', macro, {
+ cwd: exec.cwd('skipped-snapshots'),
+ cli: ['--update-snapshots'],
+ remove: false,
+ checkRun: async (t, run) => {
+ const result = await t.throwsAsync(run, {
+ message: /Snapshot assertions cannot be skipped when updating snapshots/
+ }, 'Expected fixture to throw');
+ t.snapshot(result.stats.unsavedSnapshots, 'files where snapshots could not be updated');
+ }
+});
+
+test('snapshots remain if used in a discarded try()', macro, {
+ cwd: exec.cwd('try'),
+ cli: ['--update-snapshots'],
+ remove: false
+});
+
+test('snapshots remain if skipped in a discarded try()', macro, {
+ cwd: exec.cwd('skipped-snapshots-in-try'),
+ cli: ['--update-snapshots'],
+ remove: false,
+ checkRun: async (t, run) => {
+ await t.notThrowsAsync(run, 'Expected fixture not to throw');
+ const result = await run;
+ t.snapshot(result.stats.unsavedSnapshots, 'files where snapshots could not be updated');
+ }
+});
diff --git a/test/snapshot-updates/fixtures/contains-skip-assertion.js b/test/snapshot-updates/fixtures/contains-skip-assertion.js
new file mode 100644
index 000000000..960e34451
--- /dev/null
+++ b/test/snapshot-updates/fixtures/contains-skip-assertion.js
@@ -0,0 +1,10 @@
+const test = require('ava');
+
+test('always failing snapshot', t => {
+ t.snapshot(Date.now());
+});
+
+test('skipped assertion', t => {
+ t.snapshot.skip(Date.now()); // eslint-disable-line ava/no-skip-assert
+ t.pass();
+});
diff --git a/test/snapshot-updates/fixtures/contains-skip-assertion.js.md b/test/snapshot-updates/fixtures/contains-skip-assertion.js.md
new file mode 100644
index 000000000..009f68b79
--- /dev/null
+++ b/test/snapshot-updates/fixtures/contains-skip-assertion.js.md
@@ -0,0 +1,11 @@
+# Snapshot report for `contains-skip-assertion.js`
+
+The actual snapshot is saved in `contains-skip-assertion.js.snap`.
+
+Generated by [AVA](https://avajs.dev).
+
+## always failing snapshot
+
+> Snapshot 1
+
+ 1607992742963
diff --git a/test/snapshot-updates/fixtures/contains-skip-assertion.js.snap b/test/snapshot-updates/fixtures/contains-skip-assertion.js.snap
new file mode 100644
index 000000000..4e5b37388
Binary files /dev/null and b/test/snapshot-updates/fixtures/contains-skip-assertion.js.snap differ
diff --git a/test/snapshot-updates/snapshots/test.js.md b/test/snapshot-updates/snapshots/test.js.md
index 2d85be886..c01fe5fab 100644
--- a/test/snapshot-updates/snapshots/test.js.md
+++ b/test/snapshot-updates/snapshots/test.js.md
@@ -4,46 +4,46 @@ The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
-## cannot update snapshots when file contains exclusive tests
+## cannot update snapshots when file contains skipped tests
> failed tests
- []
-
-> passed tests
-
[
{
- file: 'contains-only.js',
- title: 'exclusive test',
+ file: 'contains-skip.js',
+ title: 'always failing snapshot',
},
]
-> files where snapshots could not be updated
+> skipped tests
[
{
- file: 'contains-only.js',
+ file: 'contains-skip.js',
+ title: 'skipped test',
},
]
-## cannot update snapshots when file contains skipped tests
-
-> failed tests
+> files where snapshots could not be updated
[
{
file: 'contains-skip.js',
- title: 'always failing snapshot',
},
]
-> skipped tests
+## cannot update snapshots when file contains exclusive tests
+
+> failed tests
+
+ []
+
+> passed tests
[
{
- file: 'contains-skip.js',
- title: 'skipped test',
+ file: 'contains-only.js',
+ title: 'exclusive test',
},
]
@@ -51,7 +51,7 @@ Generated by [AVA](https://avajs.dev).
[
{
- file: 'contains-skip.js',
+ file: 'contains-only.js',
},
]
@@ -66,3 +66,31 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
'Snapshots cannot be updated when selecting specific tests by their line number.'
+
+## cannot update snapshots when skipping snapshot assertions
+
+> failed tests
+
+ [
+ {
+ file: 'contains-skip-assertion.js',
+ title: 'skipped assertion',
+ },
+ ]
+
+> passed tests
+
+ [
+ {
+ file: 'contains-skip-assertion.js',
+ title: 'always failing snapshot',
+ },
+ ]
+
+> files where snapshots could not be updated
+
+ [
+ {
+ file: 'contains-skip-assertion.js',
+ },
+ ]
diff --git a/test/snapshot-updates/snapshots/test.js.snap b/test/snapshot-updates/snapshots/test.js.snap
index fd04d3f95..25527388f 100644
Binary files a/test/snapshot-updates/snapshots/test.js.snap and b/test/snapshot-updates/snapshots/test.js.snap differ
diff --git a/test/snapshot-updates/test.js b/test/snapshot-updates/test.js
index 98767b7b4..b93fb7120 100644
--- a/test/snapshot-updates/test.js
+++ b/test/snapshot-updates/test.js
@@ -24,3 +24,10 @@ test('cannot update snapshots when selecting tests by line number', async t => {
const result = await t.throwsAsync(exec.fixture(['contains-skip.js:4', '-u']));
t.snapshot(exec.cleanOutput(result.stderr));
});
+
+test('cannot update snapshots when skipping snapshot assertions', async t => {
+ const result = await t.throwsAsync(exec.fixture(['contains-skip-assertion.js', '-u'], {env: {AVA_FORCE_CI: 'not-ci'}}));
+ t.snapshot(result.stats.failed, 'failed tests');
+ t.snapshot(result.stats.passed, 'passed tests');
+ t.snapshot(result.stats.unsavedSnapshots, 'files where snapshots could not be updated');
+});
diff --git a/xo.config.js b/xo.config.js
index 49c546469..5bd98ac41 100644
--- a/xo.config.js
+++ b/xo.config.js
@@ -2,6 +2,7 @@ module.exports = {
ignores: [
'media/**',
'test/config/fixtures/config-errors/test.js',
+ 'test/config/fixtures/mjs-with-tests/**',
'test-tap/fixture/ava-paths/target/test.js',
'test-tap/fixture/{source-map-initial,syntax-error}.js',
'test-tap/fixture/snapshots/test-sourcemaps/build/**',
@@ -26,7 +27,11 @@ module.exports = {
}
},
{
- files: ['lib/plugin-support/shared-worker-loader.js', 'lib/plugin-support/shared-workers.js'],
+ files: [
+ 'eslint-plugin-helper.js',
+ 'lib/plugin-support/shared-worker-loader.js',
+ 'lib/plugin-support/shared-workers.js'
+ ],
// TODO [engine:node@>=12]: Enable when targeting Node.js 12.
rules: {
'import/no-unresolved': 'off',