diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a52c69565..21cf3ab30 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - ts-version: [~4.4, ~4.5] + ts-version: [~4.4, ~4.5, ~4.6] steps: - uses: actions/checkout@v2 - run: rm .npmrc diff --git a/.taprc b/.taprc index 4736625a9..b1aab24e1 100644 --- a/.taprc +++ b/.taprc @@ -5,7 +5,6 @@ files: - "test-tap/reporters/*.js" - "test-tap/integration/*.js" flow: false -jobs: 2 jsx: false timeout: 300 ts: false diff --git a/docs/01-writing-tests.md b/docs/01-writing-tests.md index 69726f31d..d9b4c0a13 100644 --- a/docs/01-writing-tests.md +++ b/docs/01-writing-tests.md @@ -18,10 +18,8 @@ AVA will set `process.env.NODE_ENV` to `test`, unless the `NODE_ENV` environment To declare a test you call the `test` function you imported from AVA. Provide the required title and implementation function. Titles must be unique within each test file. The function will be called when your test is run. It's passed an [execution object](./02-execution-context.md) as its first argument. -**Note:** In order for the [enhanced assertion messages](./03-assertions.md#enhanced-assertion-messages) to behave correctly, the first argument **must** be named `t`. - ```js -const test = require('ava'); +import test from 'ava'; test('my passing test', t => { t.pass(); @@ -262,7 +260,7 @@ Available properties: * `snapshotDirectory`: directory where snapshots are stored, as a file URL string ```js -const test = require('ava'); +import test from 'ava'; console.log('Test file currently being run:', test.meta.file); ``` diff --git a/docs/02-execution-context.md b/docs/02-execution-context.md index 5b7937955..70893d987 100644 --- a/docs/02-execution-context.md +++ b/docs/02-execution-context.md @@ -5,7 +5,7 @@ Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/do Each test or hook is called with an execution context. By convention it's named `t`. ```js -const test = require('ava'); +import test from 'ava'; test('my passing test', t => { t.pass(); diff --git a/docs/03-assertions.md b/docs/03-assertions.md index a1e3393ca..ad7725f99 100644 --- a/docs/03-assertions.md +++ b/docs/03-assertions.md @@ -84,7 +84,7 @@ This won't give you as nice an experience as you'd get with the [built-in assert You'll have to configure AVA to not fail tests if no assertions are executed, because AVA can't tell if custom assertions pass. Set the `failWithoutAssertions` option to `false` in AVA's [`package.json` configuration](./06-configuration.md). ```js -const assert = require('assert'); +import assert from 'assert'; test('custom assertion', t => { assert(true); @@ -101,51 +101,51 @@ Passing assertion. Returns a boolean indicating whether the assertion passed. Failing assertion. Returns a boolean indicating whether the assertion passed. -### `.assert(value, message?)` +### `.assert(actual, message?)` -Asserts that `value` is truthy. Returns a boolean indicating whether the assertion passed. +Asserts that `actual` is truthy. Returns a boolean indicating whether the assertion passed. -### `.truthy(value, message?)` +### `.truthy(actual, message?)` -Assert that `value` is truthy. Returns a boolean indicating whether the assertion passed. +Assert that `actual` is truthy. Returns a boolean indicating whether the assertion passed. -### `.falsy(value, message?)` +### `.falsy(actual, message?)` -Assert that `value` is falsy. Returns a boolean indicating whether the assertion passed. +Assert that `actual` is falsy. Returns a boolean indicating whether the assertion passed. -### `.true(value, message?)` +### `.true(actual, message?)` -Assert that `value` is `true`. Returns a boolean indicating whether the assertion passed. +Assert that `actual` is `true`. Returns a boolean indicating whether the assertion passed. -### `.false(value, message?)` +### `.false(actual, message?)` -Assert that `value` is `false`. Returns a boolean indicating whether the assertion passed. +Assert that `actual` is `false`. Returns a boolean indicating whether the assertion passed. -### `.is(value, expected, message?)` +### `.is(actual, expected, message?)` -Assert that `value` is the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). Returns a boolean indicating whether the assertion passed. +Assert that `actual` is the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). Returns a boolean indicating whether the assertion passed. -### `.not(value, expected, message?)` +### `.not(actual, expected, message?)` -Assert that `value` is not the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). Returns a boolean indicating whether the assertion passed. +Assert that `actual` is not the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). Returns a boolean indicating whether the assertion passed. -### `.deepEqual(value, expected, message?)` +### `.deepEqual(actual, expected, message?)` -Assert that `value` is deeply equal to `expected`. See [Concordance](https://github.com/concordancejs/concordance) for details. +Assert that `actual` is deeply equal to `expected`. See [Concordance](https://github.com/concordancejs/concordance) for details. -### `.notDeepEqual(value, expected, message?)` +### `.notDeepEqual(actual, expected, message?)` -Assert that `value` is not deeply equal to `expected`. The inverse of `.deepEqual()`. Returns a boolean indicating whether the assertion passed. +Assert that `actual` is not deeply equal to `expected`. The inverse of `.deepEqual()`. Returns a boolean indicating whether the assertion passed. -### `.like(value, selector, message?)` +### `.like(actual, selector, message?)` -Assert that `value` is like `selector`. This is a variant of `.deepEqual()`, however `selector` does not need to have the same enumerable properties as `value` does. +Assert that `actual` is like `selector`. This is a variant of `.deepEqual()`, however `selector` does not need to have the same enumerable properties as `actual` does. -Instead AVA derives a *comparable* object from `value`, based on the deeply-nested properties of `selector`. This object is then compared to `selector` using `.deepEqual()`. +Instead AVA derives a *comparable* object from `actual`, based on the deeply-nested properties of `selector`. This object is then compared to `selector` using `.deepEqual()`. -Any values in `selector` that are not regular objects should be deeply equal to the corresponding values in `value`. +Any values in `selector` that are not regular objects should be deeply equal to the corresponding values in `actual`. -In the following example, the `map` property of `value` must be deeply equal to that of `selector`. However `nested.qux` is ignored, because it's not in `selector`. +In the following example, the `map` property of `actual` must be deeply equal to that of `selector`. However `nested.qux` is ignored, because it's not in `selector`. ```js t.like({ diff --git a/docs/05-command-line.md b/docs/05-command-line.md index 49743ff3d..ea1f25dae 100644 --- a/docs/05-command-line.md +++ b/docs/05-command-line.md @@ -12,36 +12,38 @@ Commands: ava debug [...] Activate Node.js inspector and run a single test file ava reset-cache Delete any temporary files and state kept by AVA, - then exit + then exit Positionals: pattern Select which test files to run. Leave empty if you want AVA to run all test files as per your configuration. Accepts glob patterns, - directories that (recursively) contain test files, and file paths. - Add a colon and specify line numbers of specific tests - to run [string] + directories that (recursively) contain test files, and file paths + optionally suffixed with a colon and comma-separated numbers and/or + ranges identifying the 1-based line(s) of specific tests to run + [string] + Options: - --version Show version number [boolean] - --color Force color output [boolean] - --config Specific JavaScript file for AVA to read its config - from, instead of using package.json or ava.config.* - files - --help Show help [boolean] - --concurrency, -c Max number of test files running at the same time - (default: CPU cores) [number] - --no-worker-threads Don't use worker threads [boolean] - --fail-fast Stop after first test failure [boolean] - --match, -m Only run tests with matching title (can be repeated) + --version Show version number [boolean] + --color Force color output [boolean] + --config Specific JavaScript file for AVA to read its config + from, instead of using package.json or ava.config.* + files + --help Show help [boolean] + -c, --concurrency Max number of test files running at the same time + (default: CPU cores) [number] + --fail-fast Stop after first test failure [boolean] + -m, --match Only run tests with matching title (can be repeated) [string] - --node-arguments Additional Node.js arguments for launching worker - processes (specify as a single string) [string] - --serial, -s Run tests serially [boolean] - --tap, -t Generate TAP output [boolean] - --timeout, -T Set global timeout (milliseconds or human-readable, - e.g. 10s, 2m) [string] - --update-snapshots, -u Update snapshots [boolean] - --verbose, -v Enable verbose output (default) [boolean] - --watch, -w Re-run tests when files change [boolean] + --no-worker-threads Don't use worker threads [boolean] + --node-arguments Additional Node.js arguments for launching worker + processes (specify as a single string) [string] + -s, --serial Run tests serially [boolean] + -t, --tap Generate TAP output [boolean] + -T, --timeout Set global timeout (milliseconds or human-readable, + e.g. 10s, 2m) [string] + -u, --update-snapshots Update snapshots [boolean] + -v, --verbose Enable verbose output (default) [boolean] + -w, --watch Re-run tests when files change [boolean] Examples: ava diff --git a/docs/06-configuration.md b/docs/06-configuration.md index 6140ddec3..ccf081d50 100644 --- a/docs/06-configuration.md +++ b/docs/06-configuration.md @@ -58,6 +58,7 @@ Arguments passed to the CLI will always take precedence over the CLI options con - `require`: extra modules to require before tests are run. Modules are required in the [worker processes](./01-writing-tests.md#process-isolation) - `timeout`: Timeouts in AVA behave differently than in other test frameworks. AVA resets a timer after each test, forcing tests to quit if no new test results were received within the specified timeout. This can be used to handle stalled tests. See our [timeout documentation](./07-test-timeouts.md) for more options. - `nodeArguments`: Configure Node.js arguments used to launch worker processes. +- `sortTestFiles`: A comparator function to sort test files with. Available only when using a `ava.config.*` file. See an example use case [here](recipes/splitting-tests-ci.md). Note that providing files on the CLI overrides the `files` option. @@ -214,9 +215,9 @@ You can now run your unit tests through `npx ava` and the integration tests thro 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: ```js -const util = require('util'); +import util from 'util'; -const test = require('ava'); +import test from 'ava'; util.inspect.defaultOptions.depth = 5; // Increase AVA's printing depth diff --git a/docs/08-common-pitfalls.md b/docs/08-common-pitfalls.md index d38be3651..8f9a1801b 100644 --- a/docs/08-common-pitfalls.md +++ b/docs/08-common-pitfalls.md @@ -42,7 +42,7 @@ test('fetches foo', async t => { If you're using callbacks, promisify the callback function using something like [`util.promisify()`](https://nodejs.org/dist/latest/docs/api/util.html#util_util_promisify_original): ```js -const {promisify} = require('util'); +import {promisify} from 'util'; test('fetches foo', async t => { const data = await promisify(fetch)(); @@ -61,7 +61,7 @@ By default AVA executes tests concurrently. This can cause problems if your test Take this contrived example: ```js -const test = require('ava'); +import test from 'ava'; let count = 0; const incr = async () => { @@ -88,7 +88,7 @@ test('increment twice', async t => { Concurrent tests allow for asynchronous tests to execute more quickly, but if they rely on shared state you this may lead to unexpected test failures. If the shared state cannot be avoided, you can execute your tests serially: ```js -const test = require('ava'); +import test from 'ava'; let count = 0; const incr = async () => { diff --git a/docs/recipes/browser-testing.md b/docs/recipes/browser-testing.md index 1ac97eee0..60e061623 100644 --- a/docs/recipes/browser-testing.md +++ b/docs/recipes/browser-testing.md @@ -27,22 +27,22 @@ Create a helper file, prefixed with an underscore. This ensures AVA does not tre `test/_setup-browser-env.js`: ```js -const browserEnv = require('browser-env'); +import browserEnv from 'browser-env'; browserEnv(); ``` By default, `browser-env` will add all global browser variables to the Node.js global scope, creating a full browser environment. This should have good compatibility with most front-end libraries, however, it's generally not a good idea to create lots of global variables if you don't need to. If you know exactly which browser globals you need, you can pass an array of them. ```js -const browserEnv = require('browser-env'); +import browserEnv from 'browser-env'; browserEnv(['window', 'document', 'navigator']); ``` You can expose more global variables by assigning them to the `global` object. For instance, jQuery is typically available through the `$` variable: ```js -const browserEnv = require('browser-env'); -const jQuery = require('jquery'); +import browserEnv from 'browser-env'; +import jQuery from 'jquery'; browserEnv(); global.$ = jQuery(window); @@ -71,7 +71,7 @@ Write your tests and enjoy a mocked browser environment. `test.js`: ```js -const test = require('ava'); +import test from 'ava'; test('Insert to DOM', t => { const div = document.createElement('div'); diff --git a/docs/recipes/endpoint-testing-with-mongoose.md b/docs/recipes/endpoint-testing-with-mongoose.md index dc2d1c40b..9ecbf6c09 100644 --- a/docs/recipes/endpoint-testing-with-mongoose.md +++ b/docs/recipes/endpoint-testing-with-mongoose.md @@ -38,14 +38,14 @@ First, include the libraries you need: ```js // Libraries required for testing -const test = require('ava'); -const request = require('supertest'); -const {MongoMemoryServer} = require('mongodb-memory-server'); -const mongoose = require('mongoose'); +import test from 'ava'; +import request from 'supertest'; +import {MongoMemoryServer} from 'mongodb-memory-server'; +import mongoose from 'mongoose'; // Your server and models -const app = require('../server'); -const User = require('../models/User'); +import app from '../server'; +import User from '../models/User'; ``` Next start the in-memory MongoDB instance and connect to Mongoose: diff --git a/docs/recipes/endpoint-testing.md b/docs/recipes/endpoint-testing.md index 386d940cc..c5adae44d 100644 --- a/docs/recipes/endpoint-testing.md +++ b/docs/recipes/endpoint-testing.md @@ -11,11 +11,11 @@ Since tests run concurrently, it's best to create a fresh server instance at lea Check out the example below: ```js -const http = require('http'); -const test = require('ava'); -const got = require('got'); -const listen = require('test-listen'); -const app = require('../app'); +import http from 'http'; +import test from 'ava'; +import got from 'got'; +import listen from 'test-listen'; +import app from '../app'; test.before(async t => { t.context.server = http.createServer(app); diff --git a/docs/recipes/isolated-mongodb-integration-tests.md b/docs/recipes/isolated-mongodb-integration-tests.md index fc6924e9e..dc597b4e5 100644 --- a/docs/recipes/isolated-mongodb-integration-tests.md +++ b/docs/recipes/isolated-mongodb-integration-tests.md @@ -23,8 +23,8 @@ In your test file, import the module, and run the server. **Make sure to run the server at the start of your file, outside of any test cases.** ```js -const test = require('ava'); -const {MongoDBServer} = require('mongomem'); +import test from 'ava'; +import {MongoDBServer} from 'mongomem'; test.before('start server', async t => { await MongoDBServer.start(); diff --git a/docs/recipes/passing-arguments-to-your-test-files.md b/docs/recipes/passing-arguments-to-your-test-files.md index 59bff010d..5d67483df 100644 --- a/docs/recipes/passing-arguments-to-your-test-files.md +++ b/docs/recipes/passing-arguments-to-your-test-files.md @@ -6,7 +6,7 @@ You can pass command line arguments to your test files. Use the `--` argument te ```js // test.js -const test = require('ava'); +import test from 'ava'; test('argv', t => { t.deepEqual(process.argv.slice(2), ['--hello', 'world']); diff --git a/docs/recipes/puppeteer.md b/docs/recipes/puppeteer.md index 4c8a0233d..4946f2402 100644 --- a/docs/recipes/puppeteer.md +++ b/docs/recipes/puppeteer.md @@ -13,7 +13,7 @@ The first step is setting up a helper to configure the environment: `./test/_withPage.js` ```js -const puppeteer = require('puppeteer'); +import puppeteer from 'puppeteer'; module.exports = async (t, run) => { const browser = await puppeteer.launch(); @@ -32,8 +32,8 @@ module.exports = async (t, run) => { `./test/main.js` ```js -const test = require('ava'); -const withPage = require('./_withPage'); +import test from 'ava'; +import withPage from './_withPage'; const url = 'https://google.com'; diff --git a/docs/recipes/react.md b/docs/recipes/react.md index d7a8ee80e..92f32c6ef 100644 --- a/docs/recipes/react.md +++ b/docs/recipes/react.md @@ -47,8 +47,8 @@ Create a helper file, prefixed with an underscore. This ensures AVA does not tre `test/_setup-enzyme-adapter.js`: ```js -const Enzyme = require('enzyme'); -const Adapter = require('enzyme-adapter-react-16'); +import Enzyme from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({ adapter: new Adapter() @@ -78,10 +78,10 @@ Then you can use Enzyme straight away: `test.js`: ```js -const test = require('ava'); -const React = require('react'); -const PropTypes = require('prop-types'); -const {shallow} = require('enzyme'); +import test from 'ava'; +import React from 'react'; +import PropTypes from 'prop-types'; +import {shallow} from 'enzyme'; const Foo = ({children}) =>
@@ -131,10 +131,10 @@ $ npm install --save-dev jsx-test-helpers Usage example: ```js -const test = require('ava'); -const React = require('react'); -const PropTypes = require('prop-types'); -const {renderJSX, JSX} = require('jsx-test-helpers'); +import test from 'ava'; +import React from 'react'; +import PropTypes from 'prop-types'; +import {renderJSX, JSX} from 'jsx-test-helpers'; const Foo = ({children}) =>
diff --git a/docs/recipes/splitting-tests-ci.md b/docs/recipes/splitting-tests-ci.md new file mode 100644 index 000000000..95849d3dd --- /dev/null +++ b/docs/recipes/splitting-tests-ci.md @@ -0,0 +1,22 @@ +# Splitting tests in CI + +AVA automatically detects whether your CI environment supports parallel builds using [ci-parallel-vars](https://www.npmjs.com/package/ci-parallel-vars). When parallel builds support is detected, AVA sorts the all detected test files by name, and splits them into chunks. Each CI machine is assigned a chunk (subset) of the tests, and then each chunk is run in parallel. + +To better distribute the tests across the machines, you can configure a custom comparator function: + +**`ava.config.js`:** + +```js +import fs from 'node:fs'; + +// Assuming 'test-data.json' structure is: +// { +// 'tests/test1.js': { order: 1 }, +// 'tests/test2.js': { order: 0 } +// } +const testData = JSON.parse(fs.readFileSync('test-data.json', 'utf8')); + +export default { + sortTestFiles: (file1, file2) => testData[file1].order - testData[file2].order, +}; +``` diff --git a/docs/recipes/testing-with-selenium-webdriverjs.md b/docs/recipes/testing-with-selenium-webdriverjs.md index 67a0d8e76..9d8a68f71 100644 --- a/docs/recipes/testing-with-selenium-webdriverjs.md +++ b/docs/recipes/testing-with-selenium-webdriverjs.md @@ -25,10 +25,9 @@ Create the following files: In both files, let's first include the packages: ```js -const test = require('ava'); -const {Builder, By, Key, until} = require('selenium-webdriver'); - -require('chromedriver'); +import test from 'ava'; +import {Builder, By, Key, until} from 'selenium-webdriver'; +import 'chromedriver'; ``` In the `bingtest.js` file, add the following code, which tests whether searching for `webdriver` on Bing, returns results. diff --git a/docs/recipes/typescript.md b/docs/recipes/typescript.md index cc054d5aa..38fe1d729 100644 --- a/docs/recipes/typescript.md +++ b/docs/recipes/typescript.md @@ -35,9 +35,6 @@ If your `package.json` has `"type": "module"`, then this is the AVA configuratio "extensions": { "ts": "module" }, - "nonSemVerExperiments": { - "configurableModuleFormat": true - }, "nodeArguments": [ "--loader=ts-node/esm" ] diff --git a/docs/recipes/vue.md b/docs/recipes/vue.md index 7c23c97ad..edb59c51c 100644 --- a/docs/recipes/vue.md +++ b/docs/recipes/vue.md @@ -30,10 +30,11 @@ The first step is setting up a helper to configure the environment to transpile ``` ```js -// ./test/_setup.js +// ./test/_setup.cjs // Set up JSDom. -require('jsdom-global')() +const jsdomGlobal = require('jsdom-global'); +jsdomGlobal(); // Fix the Date object, see . window.Date = Date diff --git a/docs/recipes/when-to-use-plan.md b/docs/recipes/when-to-use-plan.md index a08278549..d3cd2159f 100644 --- a/docs/recipes/when-to-use-plan.md +++ b/docs/recipes/when-to-use-plan.md @@ -98,7 +98,10 @@ As stated in the previous example, using the `t.throws()` assertion with `async` In most cases, it's a bad idea to use any complex branching inside your tests. A notable exception is for tests that are auto-generated (perhaps from a JSON document). Below `t.plan()` is used to ensure the correctness of the JSON input: ```js -const testData = require('./fixtures/test-definitions.json'); +import fs from 'fs'; +import path from 'path'; + +const testData = JSON.parse(fs.readFileSync(new URL('./fixtures/test-definitions.json', import.meta.url))); for (const testDefinition of testData) { test('foo or bar', t => { diff --git a/entrypoints/eslint-plugin-helper.cjs b/entrypoints/eslint-plugin-helper.cjs index 99e90638b..ab1bcfa38 100644 --- a/entrypoints/eslint-plugin-helper.cjs +++ b/entrypoints/eslint-plugin-helper.cjs @@ -90,7 +90,7 @@ function load(projectDir, overrides) { const helper = Object.freeze({ classifyFile: classifyForESLint, - classifyImport: importPath => { + classifyImport(importPath) { if (hasExtension(globs.extensions, importPath)) { // The importPath has one of the test file extensions: we can classify // it directly. diff --git a/lib/api.js b/lib/api.js index bf0cb2498..1ebe27ce5 100644 --- a/lib/api.js +++ b/lib/api.js @@ -177,13 +177,19 @@ export default class Api extends Emittery { const fileCount = selectedFiles.length; // The files must be in the same order across all runs, so sort them. - selectedFiles = selectedFiles.sort((a, b) => a.localeCompare(b, [], {numeric: true})); + const defaultComparator = (a, b) => a.localeCompare(b, [], {numeric: true}); + selectedFiles = selectedFiles.sort(this.options.sortTestFiles || defaultComparator); selectedFiles = chunkd(selectedFiles, currentIndex, totalRuns); const currentFileCount = selectedFiles.length; runStatus = new RunStatus(fileCount, {currentFileCount, currentIndex, totalRuns}, selectionInsights); } else { + // If a custom sorter was configured, use it. + if (this.options.sortTestFiles) { + selectedFiles = selectedFiles.sort(this.options.sortTestFiles); + } + runStatus = new RunStatus(selectedFiles.length, null, selectionInsights); } @@ -261,8 +267,8 @@ export default class Api extends Emittery { } const lineNumbers = getApplicableLineNumbers(globs.normalizeFileForMatching(apiOptions.projectDir, file), filter); - // Removing `providers` field because they cannot be transfered to the worker threads. - const {providers, ...forkOptions} = apiOptions; + // Removing `providers` and `sortTestFiles` fields because they cannot be transferred to the worker threads. + const {providers, sortTestFiles, ...forkOptions} = apiOptions; const options = { ...forkOptions, providerStates, diff --git a/lib/cli.js b/lib/cli.js index 3f9974732..482766850 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -21,6 +21,7 @@ import {splitPatternAndLineNumbers} from './line-numbers.js'; import {loadConfig} from './load-config.js'; import normalizeModuleTypes from './module-types.js'; import normalizeNodeArguments from './node-arguments.js'; +import pkg from './pkg.cjs'; import providerManager from './provider-manager.js'; import DefaultReporter from './reporters/default.js'; import TapReporter from './reporters/tap.js'; @@ -102,8 +103,15 @@ export default async function loadCli() { // eslint-disable-line complexity let conf; let confError; try { - const {argv: {config: configFile}} = yargs(hideBin(process.argv)).help(false); - conf = await loadConfig({configFile}); + const {argv: {config: configFile}} = yargs(hideBin(process.argv)).help(false).version(false); + const loaded = await loadConfig({configFile}); + if (loaded.unsupportedFiles.length > 0) { + console.log(chalk.magenta( + ` ${figures.warning} AVA does not support JSON config, ignoring:\n\n ${loaded.unsupportedFiles.join('\n ')}`, + )); + } + + conf = loaded.config; if (conf.configFile && path.basename(conf.configFile) !== path.relative(conf.projectDir, conf.configFile)) { console.log(chalk.magenta(` ${figures.warning} Using configuration from ${conf.configFile}`)); } @@ -132,6 +140,7 @@ export default async function loadCli() { // eslint-disable-line complexity let resetCache = false; const {argv} = yargs(hideBin(process.argv)) + .version(pkg.version) .parserConfiguration({ 'boolean-negation': true, 'camel-case-expansion': false, @@ -161,7 +170,7 @@ export default async function loadCli() { // eslint-disable-line complexity }) .command('* [...]', 'Run tests', yargs => yargs.options(FLAGS).positional('pattern', { array: true, - describe: 'Select which test files to run. Leave empty if you want AVA to run all test files as per your configuration. Accepts glob patterns, directories that (recursively) contain test files, and file paths. Add a colon and specify line numbers of specific tests to run', + describe: 'Select which test files to run. Leave empty if you want AVA to run all test files as per your configuration. Accepts glob patterns, directories that (recursively) contain test files, and file paths optionally suffixed with a colon and comma-separated numbers and/or ranges identifying the 1-based line(s) of specific tests to run', type: 'string', }), argv => { if (activeInspector) { @@ -188,7 +197,7 @@ export default async function loadCli() { // eslint-disable-line complexity }, }).positional('pattern', { demand: true, - describe: 'Glob patterns to select a single test file to debug. Add a colon and specify line numbers of specific tests to run', + describe: 'Glob pattern to select a single test file to debug, optionally suffixed with a colon and comma-separated numbers and/or ranges identifying the 1-based line(s) of specific tests to run', type: 'string', }), argv => { @@ -319,16 +328,20 @@ export default async function loadCli() { // eslint-disable-line complexity exit('’sources’ has been removed. Use ’ignoredByWatcher’ to provide glob patterns of files that the watcher should ignore.'); } - let pkg; + if (Reflect.has(conf, 'sortTestFiles') && typeof conf.sortTestFiles !== 'function') { + exit('’sortTestFiles’ must be a comparator function.'); + } + + let projectPackageObject; try { - pkg = JSON.parse(fs.readFileSync(path.resolve(projectDir, 'package.json'))); + projectPackageObject = JSON.parse(fs.readFileSync(path.resolve(projectDir, 'package.json'))); } catch (error) { if (error.code !== 'ENOENT') { throw error; } } - const {type: defaultModuleType = 'commonjs'} = pkg || {}; + const {type: defaultModuleType = 'commonjs'} = projectPackageObject || {}; const providers = []; if (Reflect.has(conf, 'typescript')) { @@ -411,6 +424,7 @@ export default async function loadCli() { // eslint-disable-line complexity moduleTypes, nodeArguments, parallelRuns, + sortTestFiles: conf.sortTestFiles, projectDir, providers, ranFromCli: true, diff --git a/lib/eslint-plugin-helper-worker.js b/lib/eslint-plugin-helper-worker.js index e53bca401..fb7ce6054 100644 --- a/lib/eslint-plugin-helper-worker.js +++ b/lib/eslint-plugin-helper-worker.js @@ -41,7 +41,7 @@ const buildGlobs = ({conf, providers, projectDir, overrideExtensions, overrideFi const resolveGlobs = async (projectDir, overrideExtensions, overrideFiles) => { if (!configCache.has(projectDir)) { - configCache.set(projectDir, loadConfig({resolveFrom: projectDir}).then(async conf => { + configCache.set(projectDir, loadConfig({resolveFrom: projectDir}).then(async ({config: conf}) => { const providers = await collectProviders({conf, projectDir}); return {conf, providers}; })); diff --git a/lib/load-config.js b/lib/load-config.js index e02809ed3..e3c70fd70 100644 --- a/lib/load-config.js +++ b/lib/load-config.js @@ -20,14 +20,15 @@ const importConfig = async ({configFile, fileForErrorMessage}) => { }; const loadConfigFile = async ({projectDir, configFile}) => { - if (!fs.existsSync(configFile)) { - return null; - } - const fileForErrorMessage = path.relative(projectDir, configFile); try { + await fs.promises.access(configFile); return {config: await importConfig({configFile, fileForErrorMessage}), configFile, fileForErrorMessage}; } catch (error) { + if (error.code === 'ENOENT') { + return null; + } + throw Object.assign(new Error(`Error loading ${fileForErrorMessage}: ${error.message}`), {parent: error}); } }; @@ -63,6 +64,20 @@ async function findRepoRoot(fromDir) { return root; } +async function checkJsonFile(searchDir) { + const file = path.join(searchDir, 'ava.config.json'); + try { + await fs.promises.access(file); + return file; + } catch (error) { + if (error.code === 'ENOENT') { + return null; + } + + throw error; + } +} + export async function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) { let packageConf = await packageConfig('ava', {cwd: resolveFrom}); const filepath = packageJsonPath(packageConf); @@ -74,6 +89,7 @@ export async function loadConfig({configFile, resolveFrom = process.cwd(), defau const allowConflictWithPackageJson = Boolean(configFile); configFile = resolveConfigFile(configFile); + const unsupportedFiles = []; let fileConf = NO_SUCH_FILE; let fileForErrorMessage; let conflicting = []; @@ -86,12 +102,17 @@ export async function loadConfig({configFile, resolveFrom = process.cwd(), defau let searchDir = projectDir; const stopAt = path.dirname(repoRoot); do { - const results = await Promise.all([ // eslint-disable-line no-await-in-loop + const [jsonFile, ...results] = await Promise.all([ // eslint-disable-line no-await-in-loop + checkJsonFile(searchDir), loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.js')}), loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.cjs')}), loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.mjs')}), ]); + if (jsonFile !== null) { + unsupportedFiles.push(jsonFile); + } + [{config: fileConf, fileForErrorMessage, configFile} = {config: NO_SUCH_FILE, fileForErrorMessage: undefined}, ...conflicting] = results.filter(result => result !== null); searchDir = path.dirname(searchDir); @@ -139,5 +160,5 @@ export async function loadConfig({configFile, resolveFrom = process.cwd(), defau } } - return config; + return {config, unsupportedFiles}; } diff --git a/lib/reporters/tap.js b/lib/reporters/tap.js index 60d2944d7..51a55cdb6 100644 --- a/lib/reporters/tap.js +++ b/lib/reporters/tap.js @@ -4,7 +4,7 @@ import path from 'node:path'; import indentString from 'indent-string'; import plur from 'plur'; import stripAnsi from 'strip-ansi'; -import supertap from 'supertap'; +import * as supertap from 'supertap'; import beautifyStack from './beautify-stack.js'; import prefixTitle from './prefix-title.js'; diff --git a/lib/test.js b/lib/test.js index 7c10ca1af..d2bb93e2e 100644 --- a/lib/test.js +++ b/lib/test.js @@ -24,16 +24,16 @@ const testMap = new WeakMap(); class ExecutionContext extends Assertions { constructor(test) { super({ - pass: () => { + pass() { test.countPassedAssertion(); }, - pending: promise => { + pending(promise) { test.addPendingAssertion(promise); }, - fail: error => { + fail(error) { test.addFailedAssertion(error); }, - skip: () => { + skip() { test.countPassedAssertion(); }, compareWithSnapshot: options => test.compareWithSnapshot(options), @@ -109,7 +109,7 @@ class ExecutionContext extends Assertions { logs: [...logs], // Don't allow modification of logs. passed, title: attemptTitle, - commit: ({retainLogs = true} = {}) => { + commit({retainLogs = true} = {}) { if (committed) { return; } @@ -132,7 +132,7 @@ class ExecutionContext extends Assertions { startingSnapshotCount, }); }, - discard: ({retainLogs = false} = {}) => { + discard({retainLogs = false} = {}) { if (committed) { test.saveFirstError(new Error('Can’t discard a result that was previously committed')); return; diff --git a/package-lock.json b/package-lock.json index 5b7e97d4e..f0f3a6562 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ava", - "version": "4.0.1", + "version": "4.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ava", - "version": "4.0.1", + "version": "4.1.0", "license": "MIT", "dependencies": { "acorn": "^8.7.0", @@ -17,32 +17,32 @@ "callsites": "^4.0.0", "cbor": "^8.1.0", "chalk": "^5.0.0", - "chokidar": "^3.5.2", + "chokidar": "^3.5.3", "chunkd": "^2.0.1", "ci-info": "^3.3.0", "ci-parallel-vars": "^1.0.1", "clean-yaml-object": "^0.1.0", "cli-truncate": "^3.1.0", - "code-excerpt": "^3.0.0", + "code-excerpt": "^4.0.0", "common-path-prefix": "^3.0.0", "concordance": "^5.0.4", "currently-unhandled": "^0.4.1", "debug": "^4.3.3", "del": "^6.0.0", - "emittery": "^0.10.0", + "emittery": "^0.10.1", "figures": "^4.0.0", - "globby": "^12.0.2", + "globby": "^13.1.1", "ignore-by-default": "^2.0.0", "indent-string": "^5.0.0", "is-error": "^2.2.2", "is-plain-object": "^5.0.0", "is-promise": "^4.0.0", "matcher": "^5.0.0", - "mem": "^9.0.1", + "mem": "^9.0.2", "ms": "^2.1.3", "p-event": "^5.0.1", "p-map": "^5.3.0", - "picomatch": "^2.3.0", + "picomatch": "^2.3.1", "pkg-conf": "^4.0.0", "plur": "^5.1.0", "pretty-ms": "^7.0.1", @@ -50,9 +50,9 @@ "slash": "^3.0.0", "stack-utils": "^2.0.5", "strip-ansi": "^7.0.1", - "supertap": "^2.0.0", + "supertap": "^3.0.1", "temp-dir": "^2.0.0", - "write-file-atomic": "^3.0.3", + "write-file-atomic": "^4.0.1", "yargs": "^17.3.1" }, "bin": { @@ -61,22 +61,22 @@ "devDependencies": { "@ava/test": "github:avajs/test", "@ava/typescript": "^3.0.1", - "@sinonjs/fake-timers": "^8.1.0", + "@sinonjs/fake-timers": "^9.1.1", "ansi-escapes": "^5.0.0", "c8": "^7.11.0", "delay": "^5.0.0", - "execa": "^6.0.0", - "fs-extra": "^10.0.0", + "execa": "^6.1.0", + "fs-extra": "^10.0.1", "get-stream": "^6.0.1", "replace-string": "^4.0.0", - "sinon": "^12.0.1", - "tap": "^15.1.5", + "sinon": "^13.0.1", + "tap": "^16.0.0", "temp-write": "^5.0.0", "tempy": "^2.0.0", "touch": "^3.1.0", "tsd": "^0.19.1", - "typescript": "^4.4.4", - "xo": "^0.47.0", + "typescript": "^4.6.2", + "xo": "^0.48.0", "zen-observable": "^0.8.15" }, "engines": { @@ -274,6 +274,15 @@ } } }, + "node_modules/@ava/v4/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/@ava/v4/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -305,6 +314,18 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@ava/v4/node_modules/code-excerpt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", + "dev": true, + "dependencies": { + "convert-to-spaces": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@ava/v4/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -323,6 +344,47 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/@ava/v4/node_modules/convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@ava/v4/node_modules/globby": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", + "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", + "dev": true, + "dependencies": { + "array-union": "^3.0.1", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.7", + "ignore": "^5.1.9", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ava/v4/node_modules/globby/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ava/v4/node_modules/p-event": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", @@ -365,6 +427,64 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@ava/v4/node_modules/supertap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-2.0.0.tgz", + "integrity": "sha512-jRzcXlCeDYvKoZGA5oRhYyR3jUIYu0enkSxtmAgHRlD7HwrovTpH4bDSi0py9FtuA8si9cW/fKommJHuaoDHJA==", + "dev": true, + "dependencies": { + "arrify": "^2.0.1", + "indent-string": "^4.0.0", + "js-yaml": "^3.14.0", + "serialize-error": "^7.0.1", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ava/v4/node_modules/supertap/node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ava/v4/node_modules/supertap/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ava/v4/node_modules/supertap/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ava/v4/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", @@ -425,64 +545,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/eslint-parser": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.16.5.tgz", - "integrity": "sha512-mUqYa46lgWqHKQ33Q6LNCGp/wPR3eqOYTUixHFsfrSQqRxH0+WOzca75iEjFr5RDGH1dDz622LaHhLOzOuQRUA==", - "dev": true, - "dependencies": { - "eslint-scope": "^5.1.1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.11.0", - "eslint": "^7.5.0 || ^8.0.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@babel/eslint-parser/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.7.tgz", @@ -798,14 +860,14 @@ "dev": true }, "node_modules/@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", + "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", @@ -1010,18 +1072,18 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.1.tgz", + "integrity": "sha512-Wp5vwlZ0lOqpSYGKqr53INws9HLkt6JDc/pDZcPf7bchQnrXJMXPns8CXx0hFikMSGSWfvtvvpb2gtMVfkWagA==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.7.0" } }, "node_modules/@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", + "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.6.0", @@ -1375,15 +1437,6 @@ "ajv": "^6.9.1" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-escapes": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", @@ -1496,6 +1549,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "dev": true, "engines": { "node": ">=12" }, @@ -1544,6 +1598,8 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -1553,6 +1609,8 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.8" } @@ -1570,13 +1628,17 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -1585,7 +1647,9 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/balanced-match": { "version": "1.0.2", @@ -1597,6 +1661,8 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -1793,6 +1859,18 @@ "node": ">=8" } }, + "node_modules/caching-transform/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -1857,7 +1935,9 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/cbor": { "version": "8.1.0", @@ -1882,9 +1962,15 @@ } }, "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2040,14 +2126,14 @@ } }, "node_modules/code-excerpt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", - "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", "dependencies": { - "convert-to-spaces": "^1.0.1" + "convert-to-spaces": "^2.0.1" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/color-convert": { @@ -2079,6 +2165,8 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2128,9 +2216,9 @@ } }, "node_modules/confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, "node_modules/convert-source-map": { @@ -2143,18 +2231,20 @@ } }, "node_modules/convert-to-spaces": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", - "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", "engines": { - "node": ">= 4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/cosmiconfig": { "version": "7.0.1", @@ -2177,6 +2267,8 @@ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "js-yaml": "^3.13.1", "lcov-parse": "^1.0.0", @@ -2236,6 +2328,8 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -2455,6 +2549,8 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -2496,6 +2592,8 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -2508,9 +2606,9 @@ "dev": true }, "node_modules/emittery": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.0.tgz", - "integrity": "sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.1.tgz", + "integrity": "sha512-OBSS9uVXbpgqEGq2V5VnpfCu9vSnfiR9eYVJmxFYToNIcWRHkM4BAFbJe/PWjf/pQdEL7OPxd2jOW/bJiyX7gg==", "engines": { "node": ">=12" }, @@ -2549,18 +2647,6 @@ "node": ">=0.6" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/env-editor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-1.0.0.tgz", @@ -2675,24 +2761,23 @@ } }, "node_modules/eslint": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.6.0.tgz", - "integrity": "sha512-UvxdOJ7mXFlw7iuHZA4jmzPaUqIw54mZrv+XPYKNbKdLR0et4rf60lIZUU9kiNtnzzMzGWxMV+tQ7uG7JG8DPw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", + "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.2.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.3.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2700,7 +2785,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", @@ -2711,9 +2796,7 @@ "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", @@ -2742,21 +2825,21 @@ } }, "node_modules/eslint-config-xo": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.39.0.tgz", - "integrity": "sha512-QX+ZnQgzy/UtgF8dksIiIBzpYoEKmiL0CmZ8O0Gnby7rGXg8Cny1CXirmHp1zKYIpO7BuTmtWj8eUYOsGr0IGQ==", + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.40.0.tgz", + "integrity": "sha512-msI1O0JGxeK2bbExg3U6EGaWKcjhOFzEjwzObywG/DC5GSNZTOyJT+b2l9MZGBeZsVdxfIGwdXTNeWXl8cN9iw==", "dev": true, "dependencies": { - "confusing-browser-globals": "1.0.10" + "confusing-browser-globals": "1.0.11" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" }, "peerDependencies": { - "eslint": ">=7.20.0" + "eslint": ">=8.6.0" } }, "node_modules/eslint-formatter-pretty": { @@ -3075,9 +3158,9 @@ } }, "node_modules/eslint-plugin-ava": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-13.1.0.tgz", - "integrity": "sha512-Bdwyqv4Xh+4ekqbk601HcZNcx8+9ClNGz5GdbC2hv977jUPHQPDMx2arTD3zi1EeyOnOG2Kx22Ow3wecbPCRjQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-13.2.0.tgz", + "integrity": "sha512-i5B5izsEdERKQLruk1nIWzTTE7C26/ju8qQf7JeyRv32XT2lRMW0zMFZNhIrEf5/5VvpSz2rqrV7UcjClGbKsw==", "dev": true, "dependencies": { "enhance-visitors": "^1.0.0", @@ -3180,9 +3263,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", - "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", "dev": true, "dependencies": { "array-includes": "^3.1.4", @@ -3190,14 +3273,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.1", + "eslint-module-utils": "^2.7.2", "has": "^1.0.3", "is-core-module": "^2.8.0", "is-glob": "^4.0.3", "minimatch": "^3.0.4", "object.values": "^1.1.5", "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "tsconfig-paths": "^3.12.0" }, "engines": { "node": ">=4" @@ -3323,23 +3406,22 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "39.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-39.0.0.tgz", - "integrity": "sha512-fd5RK2FtYjGcIx3wra7csIE/wkkmBo22T1gZtRTsLr1Mb+KsFKJ+JOdSqhHXQUrI/JTs/Mon64cEYzTgSCbltw==", + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-40.1.0.tgz", + "integrity": "sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", - "ci-info": "^3.2.0", + "@babel/helper-validator-identifier": "^7.15.7", + "ci-info": "^3.3.0", "clean-regexp": "^1.0.0", - "eslint-template-visitor": "^2.3.2", "eslint-utils": "^3.0.0", "esquery": "^1.4.0", - "indent-string": "4", + "indent-string": "^4.0.0", "is-builtin-module": "^3.1.0", "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.23", + "regexp-tree": "^0.1.24", "safe-regex": "^2.1.1", "semver": "^7.3.5", "strip-indent": "^3.0.0" @@ -3370,9 +3452,9 @@ "dev": true }, "node_modules/eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -3382,31 +3464,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint-template-visitor": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", - "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.16", - "@babel/eslint-parser": "^7.12.16", - "eslint-visitor-keys": "^2.0.0", - "esquery": "^1.3.1", - "multimap": "^1.1.0" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-template-visitor/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -3435,9 +3492,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3546,15 +3603,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3601,14 +3649,14 @@ } }, "node_modules/espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "dependencies": { "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3690,9 +3738,9 @@ "dev": true }, "node_modules/execa": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-6.0.0.tgz", - "integrity": "sha512-m4wU9j4Z9nXXoqT8RSfl28JSwmMNLFF69OON8H/lL3NeU0tNpGz313bcOfYoBBHokB0dC2tMl3VUcKgHELhL2Q==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", + "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", @@ -3700,9 +3748,9 @@ "human-signals": "^3.0.1", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^5.0.1", + "npm-run-path": "^5.1.0", "onetime": "^6.0.0", - "signal-exit": "^3.0.5", + "signal-exit": "^3.0.7", "strip-final-newline": "^3.0.0" }, "engines": { @@ -3716,7 +3764,9 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/extsprintf": { "version": "1.3.0", @@ -3725,7 +3775,9 @@ "dev": true, "engines": [ "node >=0.6.0" - ] + ], + "optional": true, + "peer": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -3739,9 +3791,9 @@ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" }, "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3750,7 +3802,7 @@ "micromatch": "^4.0.4" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" } }, "node_modules/fast-json-stable-stringify": { @@ -3893,6 +3945,8 @@ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -3902,6 +3956,8 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -3938,9 +3994,9 @@ "dev": true }, "node_modules/fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -4081,6 +4137,8 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -4132,14 +4190,13 @@ } }, "node_modules/globby": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-12.0.2.tgz", - "integrity": "sha512-lAsmb/5Lww4r7MM9nCCliDZVIKbZTavrsunAsHLr9oHthrZP1qi7/gAnHOsUs9bLvEt2vKVJhHmxuL7QbDuPdQ==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.1.tgz", + "integrity": "sha512-XMzoDZbGZ37tufiv7g0N4F/zp3zkwdFtVbV3EHsVl1KQr4RPLfNoT068/97RPshz2J5xYNEjLKKBKaGHifBd3Q==", "dependencies": { - "array-union": "^3.0.1", "dir-glob": "^3.0.1", - "fast-glob": "^3.2.7", - "ignore": "^5.1.8", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^4.0.0" }, @@ -4171,6 +4228,8 @@ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=4" } @@ -4181,6 +4240,8 @@ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", "dev": true, + "optional": true, + "peer": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -4315,6 +4376,8 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -4813,7 +4876,8 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "node_modules/is-unc-path": { "version": "1.0.0", @@ -4887,7 +4951,9 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", @@ -5127,7 +5193,9 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/jsesc": { "version": "2.5.2", @@ -5158,7 +5226,9 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -5176,7 +5246,9 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/json5": { "version": "2.2.0", @@ -5210,6 +5282,8 @@ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -5240,6 +5314,8 @@ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", "dev": true, + "optional": true, + "peer": true, "bin": { "lcov-parse": "bin/cli.js" } @@ -5258,9 +5334,9 @@ } }, "node_modules/libtap": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.3.tgz", - "integrity": "sha512-BfbhcSlcFngZWYvDt+gs4m1BkjP0LaFEg6+4FBAXD0E8Br95wpXCCvS5JZHW1a5QPWMrFD4LhsqBpTPRB3Em8g==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.3.0.tgz", + "integrity": "sha512-yU5uSY987sVwpWiR5h84ZM96bxvmCQFZ/bOEJ1M7+Us8oez25fLmmLNGFRFGWi2PzuLqAzqzESH7HCaZ/b9IZA==", "dev": true, "dependencies": { "async-hook-domain": "^2.0.4", @@ -5272,11 +5348,10 @@ "own-or-env": "^1.0.2", "signal-exit": "^3.0.4", "stack-utils": "^2.0.4", - "tap-parser": "^10.0.1", + "tap-parser": "^11.0.0", "tap-yaml": "^1.0.0", "tcompare": "^5.0.6", - "trivial-deferred": "^1.0.1", - "yapool": "^1.0.0" + "trivial-deferred": "^1.0.1" }, "engines": { "node": ">=10" @@ -5397,6 +5472,8 @@ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.8.6" } @@ -5571,9 +5648,9 @@ } }, "node_modules/mem": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.1.tgz", - "integrity": "sha512-f4uEX3Ley9FZqcFIRSBr2q43x1bJQeDvsxgkSN/BPnA7jY9Aue4sBU2dsjmpDwiaY/QY1maNCeosbUHQWzzdQw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", + "integrity": "sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==", "dependencies": { "map-age-cleaner": "^0.1.3", "mimic-fn": "^4.0.0" @@ -5666,6 +5743,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true, + "peer": true, "engines": { "node": ">= 0.6" } @@ -5675,6 +5753,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, + "peer": true, "dependencies": { "mime-db": "1.51.0" }, @@ -5771,12 +5850,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/multimap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", - "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5791,27 +5864,18 @@ "peer": true }, "node_modules/nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", + "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": ">=5", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" } }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -5877,9 +5941,9 @@ } }, "node_modules/npm-run-path": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.0.1.tgz", - "integrity": "sha512-ybBJQUSyFwEEhqO2lXmyKOl9ucHtyZBWVM0h0FiMfT/+WKxCUZFa95qAR2X3w/w6oigN3B0b2UNHZbD+kdfD5w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -6193,6 +6257,8 @@ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -6666,7 +6732,9 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/picocolors": { "version": "1.0.0", @@ -6922,15 +6990,6 @@ "node": ">=8" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/proto-props": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz", @@ -6944,7 +7003,9 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/punycode": { "version": "2.1.1", @@ -6960,6 +7021,8 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.6" } @@ -7215,6 +7278,8 @@ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, + "optional": true, + "peer": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -7351,7 +7416,9 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/schema-utils": { "version": "3.1.1", @@ -7463,21 +7530,21 @@ } }, "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/sinon": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", - "integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz", + "integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^8.1.0", - "@sinonjs/samsam": "^6.0.2", + "@sinonjs/fake-timers": "^9.0.0", + "@sinonjs/samsam": "^6.1.1", "diff": "^5.0.0", - "nise": "^5.1.0", + "nise": "^5.1.1", "supports-color": "^7.2.0" }, "funding": { @@ -7595,6 +7662,8 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -7736,53 +7805,17 @@ } }, "node_modules/supertap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supertap/-/supertap-2.0.0.tgz", - "integrity": "sha512-jRzcXlCeDYvKoZGA5oRhYyR3jUIYu0enkSxtmAgHRlD7HwrovTpH4bDSi0py9FtuA8si9cW/fKommJHuaoDHJA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", + "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", "dependencies": { - "arrify": "^2.0.1", - "indent-string": "^4.0.0", - "js-yaml": "^3.14.0", + "indent-string": "^5.0.0", + "js-yaml": "^3.14.1", "serialize-error": "^7.0.1", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/supertap/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/supertap/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "engines": { - "node": ">=8" - } - }, - "node_modules/supertap/node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/supertap/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/supports-color": { @@ -7811,9 +7844,9 @@ } }, "node_modules/tap": { - "version": "15.1.5", - "resolved": "https://registry.npmjs.org/tap/-/tap-15.1.5.tgz", - "integrity": "sha512-ha9ify0cagIOENV5D+T8ys+FFOWqPaWAKk66hjtUWjywXdGmnL8LRxloZa8sHiaB+Az1GYx4ufEaflOpedSCbQ==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.0.0.tgz", + "integrity": "sha512-EnrFFUIn+/089C051WYPXxNlAnXJ1TkKerh0Osz9lK0Ynb+X5FWBEZxWcZLVKiucdTnV5g97NL8Xaw1CuAkj4Q==", "bundleDependencies": [ "ink", "treport", @@ -7826,7 +7859,6 @@ "@isaacs/import-jsx": "*", "@types/react": "*", "chokidar": "^3.3.0", - "coveralls": "^3.0.11", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", @@ -7835,7 +7867,7 @@ "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", "jackspeak": "^1.4.1", - "libtap": "^1.1.3", + "libtap": "^1.3.0", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", @@ -7844,10 +7876,10 @@ "rimraf": "^3.0.0", "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", - "tap-mocha-reporter": "^5.0.0", - "tap-parser": "^10.0.1", + "tap-mocha-reporter": "^5.0.3", + "tap-parser": "^11.0.1", "tap-yaml": "^1.0.0", - "tcompare": "^5.0.6", + "tcompare": "^5.0.7", "treport": "*", "which": "^2.0.2" }, @@ -7855,17 +7887,21 @@ "tap": "bin/run.js" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { + "coveralls": "^3.1.1", "flow-remove-types": ">=2.112.0", "ts-node": ">=8.5.2", "typescript": ">=3.7.2" }, "peerDependenciesMeta": { + "coveralls": { + "optional": true + }, "flow-remove-types": { "optional": true }, @@ -7878,9 +7914,9 @@ } }, "node_modules/tap-mocha-reporter": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz", - "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.3.tgz", + "integrity": "sha512-6zlGkaV4J+XMRFkN0X+yuw6xHbE9jyCZ3WUKfw4KxMyRGOpYSRuuQTRJyWX88WWuLdVTuFbxzwXhXuS2XE6o0g==", "dev": true, "dependencies": { "color-support": "^1.1.0", @@ -7888,7 +7924,7 @@ "diff": "^4.0.1", "escape-string-regexp": "^2.0.0", "glob": "^7.0.5", - "tap-parser": "^10.0.0", + "tap-parser": "^11.0.0", "tap-yaml": "^1.0.0", "unicode-length": "^2.0.2" }, @@ -7918,13 +7954,13 @@ } }, "node_modules/tap-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz", - "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.1.tgz", + "integrity": "sha512-5ow0oyFOnXVSALYdidMX94u0GEjIlgc/BPFYLx0yRh9hb8+cFGNJqJzDJlUqbLOwx8+NBrIbxCWkIQi7555c0w==", "dev": true, "dependencies": { "events-to-array": "^1.0.1", - "minipass": "^3.0.0", + "minipass": "^3.1.6", "tap-yaml": "^1.0.0" }, "bin": { @@ -8423,15 +8459,6 @@ "node": ">=8" } }, - "node_modules/tap/node_modules/@isaacs/import-jsx/node_modules/callsites": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/tap/node_modules/@types/prop-types": { "version": "15.7.4", "dev": true, @@ -8575,6 +8602,15 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/tap/node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tap/node_modules/caniuse-lite": { "version": "1.0.30001279", "dev": true, @@ -9135,7 +9171,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/minipass": { - "version": "3.1.5", + "version": "3.1.6", "dev": true, "inBundle": true, "license": "ISC", @@ -9520,13 +9556,13 @@ } }, "node_modules/tap/node_modules/tap-parser": { - "version": "10.1.0", + "version": "11.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "events-to-array": "^1.0.1", - "minipass": "^3.0.0", + "minipass": "^3.1.6", "tap-yaml": "^1.0.0" }, "bin": { @@ -9555,7 +9591,7 @@ } }, "node_modules/tap/node_modules/treport": { - "version": "3.0.2", + "version": "3.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -9565,7 +9601,7 @@ "chalk": "^3.0.0", "ink": "^3.2.0", "ms": "^2.1.2", - "tap-parser": "^10.0.1", + "tap-parser": "^11.0.0", "unicode-length": "^2.0.2" }, "peerDependencies": { @@ -10062,6 +10098,8 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -10172,6 +10210,8 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -10183,7 +10223,9 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/type-check": { "version": "0.4.0", @@ -10222,14 +10264,15 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -10384,6 +10427,8 @@ "engines": [ "node >=0.6.0" ], + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -10661,20 +10706,21 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", "dependencies": { "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" } }, "node_modules/xo": { - "version": "0.47.0", - "resolved": "https://registry.npmjs.org/xo/-/xo-0.47.0.tgz", - "integrity": "sha512-QHRIpaPSG7tK7PX4K4fqe0V4EH1u2IkM7Pr356u1fKcVsZskw7i9gfEqyBLsnnc4e4Y8gnLtIqasLJsGPqM8sA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/xo/-/xo-0.48.0.tgz", + "integrity": "sha512-f0sbQGJoML3nwOLG7EIAJroBypmLokoGJqTPN+bI/oogKLMciqWBEiFh9Vpxnfwxafq1AkHoWrQZQWSflDCG1w==", "bundleDependencies": [ "@typescript-eslint/eslint-plugin", "@typescript-eslint/parser", @@ -10682,30 +10728,30 @@ ], "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.0.4", + "@eslint/eslintrc": "^1.0.5", "@typescript-eslint/eslint-plugin": "*", "@typescript-eslint/parser": "*", "arrify": "^3.0.0", "cosmiconfig": "^7.0.1", "define-lazy-prop": "^3.0.0", - "eslint": "^8.3.0", + "eslint": "^8.8.0", "eslint-config-prettier": "^8.3.0", - "eslint-config-xo": "^0.39.0", + "eslint-config-xo": "^0.40.0", "eslint-config-xo-typescript": "*", "eslint-formatter-pretty": "^4.1.0", "eslint-import-resolver-webpack": "^0.13.2", - "eslint-plugin-ava": "^13.1.0", + "eslint-plugin-ava": "^13.2.0", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import": "^2.25.3", + "eslint-plugin-import": "^2.25.4", "eslint-plugin-no-use-extend-native": "^0.5.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-unicorn": "^39.0.0", - "esm-utils": "^2.0.0", + "eslint-plugin-unicorn": "^40.1.0", + "esm-utils": "^2.0.1", "find-cache-dir": "^3.3.2", - "find-up": "^6.2.0", + "find-up": "^6.3.0", "get-stdin": "^9.0.0", - "globby": "^12.0.2", + "globby": "^13.1.1", "imurmurhash": "^0.1.4", "json-stable-stringify-without-jsonify": "^1.0.1", "json5": "^2.2.0", @@ -10713,11 +10759,11 @@ "meow": "^10.1.2", "micromatch": "^4.0.4", "open-editor": "^4.0.0", - "prettier": "^2.5.0", + "prettier": "^2.5.1", "semver": "^7.3.5", "slash": "^4.0.0", "to-absolute-glob": "^2.0.2", - "typescript": "^4.5.2" + "typescript": "^4.5.5" }, "bin": { "xo": "cli.js" @@ -10771,13 +10817,14 @@ "license": "MIT" }, "node_modules/xo/node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.4.0", + "version": "5.11.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/type-utils": "5.11.0", + "@typescript-eslint/utils": "5.11.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -10803,7 +10850,7 @@ } }, "node_modules/xo/node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "5.1.9", + "version": "5.2.0", "dev": true, "inBundle": true, "license": "MIT", @@ -10814,7 +10861,6 @@ "node_modules/xo/node_modules/@typescript-eslint/experimental-utils": { "version": "5.4.0", "dev": true, - "inBundle": true, "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -10836,14 +10882,14 @@ } }, "node_modules/xo/node_modules/@typescript-eslint/parser": { - "version": "5.4.0", + "version": "5.11.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", "debug": "^4.3.2" }, "engines": { @@ -10863,13 +10909,31 @@ } }, "node_modules/xo/node_modules/@typescript-eslint/scope-manager": { - "version": "5.4.0", + "version": "5.11.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/xo/node_modules/@typescript-eslint/type-utils": { + "version": "5.11.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "5.11.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -10877,10 +10941,18 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/xo/node_modules/@typescript-eslint/types": { - "version": "5.4.0", + "version": "5.11.0", "dev": true, "inBundle": true, "license": "MIT", @@ -10893,13 +10965,13 @@ } }, "node_modules/xo/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.4.0", + "version": "5.11.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -10919,26 +10991,17 @@ } } }, - "node_modules/xo/node_modules/@typescript-eslint/typescript-estree/node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/xo/node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.0.4", + "version": "11.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" }, "engines": { @@ -10949,7 +11012,7 @@ } }, "node_modules/xo/node_modules/@typescript-eslint/typescript-estree/node_modules/ignore": { - "version": "5.1.9", + "version": "5.2.0", "dev": true, "inBundle": true, "license": "MIT", @@ -10966,13 +11029,37 @@ "node": ">=8" } }, + "node_modules/xo/node_modules/@typescript-eslint/utils": { + "version": "5.11.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/xo/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.4.0", + "version": "5.11.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/types": "5.11.0", "eslint-visitor-keys": "^3.0.0" }, "engines": { @@ -10983,6 +11070,15 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/xo/node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/xo/node_modules/braces": { "version": "3.0.2", "dev": true, @@ -11026,7 +11122,7 @@ } }, "node_modules/xo/node_modules/debug": { - "version": "4.3.2", + "version": "4.3.3", "dev": true, "inBundle": true, "license": "MIT", @@ -11073,7 +11169,7 @@ } }, "node_modules/xo/node_modules/eslint-config-xo-typescript": { - "version": "0.47.1", + "version": "0.50.0", "dev": true, "inBundle": true, "license": "MIT", @@ -11084,7 +11180,7 @@ "url": "https://github.com/sponsors/sindresorhus" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": ">=5.0.0", + "@typescript-eslint/eslint-plugin": ">=5.8.0", "eslint": ">=8.0.0", "typescript": ">=4.4" } @@ -11139,7 +11235,7 @@ } }, "node_modules/xo/node_modules/eslint-visitor-keys": { - "version": "3.1.0", + "version": "3.2.0", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -11169,7 +11265,7 @@ } }, "node_modules/xo/node_modules/fast-glob": { - "version": "3.2.7", + "version": "3.2.11", "dev": true, "inBundle": true, "license": "MIT", @@ -11181,7 +11277,7 @@ "micromatch": "^4.0.4" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" } }, "node_modules/xo/node_modules/fastq": { @@ -11206,12 +11302,12 @@ } }, "node_modules/xo/node_modules/find-up": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.2.0.tgz", - "integrity": "sha512-yWHzMzXCaFoABSnFTCPKNFlYoq4mSga9QLRRKOCLSJ33hSkzROB14ITbAWW0QDQDyuzsPQ33S1DsOWQb/oW1yA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dev": true, "dependencies": { - "locate-path": "^7.0.0", + "locate-path": "^7.1.0", "path-exists": "^5.0.0" }, "engines": { @@ -11270,9 +11366,9 @@ } }, "node_modules/xo/node_modules/locate-path": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.0.0.tgz", - "integrity": "sha512-+cg2yXqDUKfo4hsFxwa3G1cBJeA+gs1vD8FyV9/odWoUlQe/4syxHQ5DPtKjtfm6gnKbZzjCqzX03kXosvZB1w==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.1.0.tgz", + "integrity": "sha512-HNx5uOnYeK4SxEoid5qnhRfprlJeGMzFRKPLCf/15N3/B4AiofNwC/yq7VBKdVk9dx7m+PiYCJOGg55JYTAqoQ==", "dev": true, "dependencies": { "p-locate": "^6.0.0" @@ -11393,7 +11489,7 @@ } }, "node_modules/xo/node_modules/picomatch": { - "version": "2.3.0", + "version": "2.3.1", "dev": true, "inBundle": true, "license": "MIT", @@ -11741,12 +11837,6 @@ "node": ">= 6" } }, - "node_modules/yapool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", - "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", - "dev": true - }, "node_modules/yargs": { "version": "17.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", diff --git a/package.json b/package.json index cb2c85406..afe22b900 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ava", - "version": "4.0.1", + "version": "4.1.0", "description": "Node.js test runner that lets you develop with confidence.", "license": "MIT", "repository": "avajs/ava", @@ -78,32 +78,32 @@ "callsites": "^4.0.0", "cbor": "^8.1.0", "chalk": "^5.0.0", - "chokidar": "^3.5.2", + "chokidar": "^3.5.3", "chunkd": "^2.0.1", "ci-info": "^3.3.0", "ci-parallel-vars": "^1.0.1", "clean-yaml-object": "^0.1.0", "cli-truncate": "^3.1.0", - "code-excerpt": "^3.0.0", + "code-excerpt": "^4.0.0", "common-path-prefix": "^3.0.0", "concordance": "^5.0.4", "currently-unhandled": "^0.4.1", "debug": "^4.3.3", "del": "^6.0.0", - "emittery": "^0.10.0", + "emittery": "^0.10.1", "figures": "^4.0.0", - "globby": "^12.0.2", + "globby": "^13.1.1", "ignore-by-default": "^2.0.0", "indent-string": "^5.0.0", "is-error": "^2.2.2", "is-plain-object": "^5.0.0", "is-promise": "^4.0.0", "matcher": "^5.0.0", - "mem": "^9.0.1", + "mem": "^9.0.2", "ms": "^2.1.3", "p-event": "^5.0.1", "p-map": "^5.3.0", - "picomatch": "^2.3.0", + "picomatch": "^2.3.1", "pkg-conf": "^4.0.0", "plur": "^5.1.0", "pretty-ms": "^7.0.1", @@ -111,30 +111,30 @@ "slash": "^3.0.0", "stack-utils": "^2.0.5", "strip-ansi": "^7.0.1", - "supertap": "^2.0.0", + "supertap": "^3.0.1", "temp-dir": "^2.0.0", - "write-file-atomic": "^3.0.3", + "write-file-atomic": "^4.0.1", "yargs": "^17.3.1" }, "devDependencies": { "@ava/test": "github:avajs/test", "@ava/typescript": "^3.0.1", - "@sinonjs/fake-timers": "^8.1.0", + "@sinonjs/fake-timers": "^9.1.1", "ansi-escapes": "^5.0.0", "c8": "^7.11.0", "delay": "^5.0.0", - "execa": "^6.0.0", - "fs-extra": "^10.0.0", + "execa": "^6.1.0", + "fs-extra": "^10.0.1", "get-stream": "^6.0.1", "replace-string": "^4.0.0", - "sinon": "^12.0.1", - "tap": "^15.1.5", + "sinon": "^13.0.1", + "tap": "^16.0.0", "temp-write": "^5.0.0", "tempy": "^2.0.0", "touch": "^3.1.0", "tsd": "^0.19.1", - "typescript": "^4.4.4", - "xo": "^0.47.0", + "typescript": "^4.6.2", + "xo": "^0.48.0", "zen-observable": "^0.8.15" }, "peerDependencies": { diff --git a/readme.md b/readme.md index 682315ce0..78b4a9cd9 100644 --- a/readme.md +++ b/readme.md @@ -71,7 +71,7 @@ Don't forget to configure the `test` script in your `package.json` as per above. Create a file named `test.js` in the project root directory: ```js -const test = require('ava'); +import test from 'ava'; test('foo', t => { t.pass(); @@ -139,15 +139,16 @@ We have a growing list of [common pitfalls](docs/08-common-pitfalls.md) you may ### Recipes -- [Shared workers](docs/recipes/shared-workers.md) - [Test setup](docs/recipes/test-setup.md) -- [Code coverage](docs/recipes/code-coverage.md) +- [TypeScript](docs/recipes/typescript.md) +- [Shared workers](docs/recipes/shared-workers.md) - [Watch mode](docs/recipes/watch-mode.md) -- [Endpoint testing](docs/recipes/endpoint-testing.md) - [When to use `t.plan()`](docs/recipes/when-to-use-plan.md) -- [Browser testing](docs/recipes/browser-testing.md) -- [TypeScript](docs/recipes/typescript.md) - [Passing arguments to your test files](docs/recipes/passing-arguments-to-your-test-files.md) +- [Splitting tests in CI](docs/recipes/splitting-tests-ci.md) +- [Code coverage](docs/recipes/code-coverage.md) +- [Endpoint testing](docs/recipes/endpoint-testing.md) +- [Browser testing](docs/recipes/browser-testing.md) - [Testing Vue.js components](docs/recipes/vue.md) - [Debugging tests with Chrome DevTools](docs/recipes/debugging-with-chrome-devtools.md) - [Debugging tests with VSCode](docs/recipes/debugging-with-vscode.md) diff --git a/test-d/deep-equal.ts b/test-d/deep-equal.ts new file mode 100644 index 000000000..7cc0f1b72 --- /dev/null +++ b/test-d/deep-equal.ts @@ -0,0 +1,30 @@ +import {expectType} from 'tsd'; + +import test from '..'; + +test('actual extends expected', t => { + type Expected = {foo: [1, 2, 3]}; + const expected: Expected = {foo: [1, 2, 3]}; + const actual = {foo: [1, 2, 3]}; + if (t.deepEqual(actual, expected)) { + expectType(actual); + } +}); + +test('expected extends actual', t => { + type Expected = {foo: Array}; + type Actual = {foo: number[]}; + const expected: Expected = {foo: [1, 2, 3]}; + const actual: Actual = {foo: [1, 2, 3]}; + if (t.deepEqual(actual, expected)) { + expectType(expected); + } +}); + +test('neither extends the each other', t => { + type Expected = {readonly foo: readonly [1, 2, 3]}; + type Actual = {foo: number[]}; + const expected: Expected = {foo: [1, 2, 3]}; + const actual: Actual = {foo: [1, 2, 3]}; + t.deepEqual(actual, expected); +}); diff --git a/test-d/implementation-result.ts b/test-d/implementation-result.ts index 35574c376..1286d42eb 100644 --- a/test-d/implementation-result.ts +++ b/test-d/implementation-result.ts @@ -2,7 +2,7 @@ import test from '..'; test('return a promise-like', t => ({ - then(resolve) { + then(resolve) { // eslint-disable-line unicorn/no-thenable resolve?.(); // eslint-disable-line @typescript-eslint/no-floating-promises }, })); @@ -16,5 +16,5 @@ test('return a subscribable', t => ({ test.after('return anything else', t => ({ foo: 'bar', subscribe() {}, - then() {}, + then() {}, // eslint-disable-line unicorn/no-thenable })); diff --git a/test-tap/assert.js b/test-tap/assert.js index fe86cb279..c21bbc7d9 100644 --- a/test-tap/assert.js +++ b/test-tap/assert.js @@ -16,20 +16,20 @@ let lastPassed = false; const AssertionsBase = class extends assert.Assertions { constructor(overwrites = {}) { super({ - pass: () => { + pass() { lastPassed = true; }, - pending: promise => { + pending(promise) { promise.then(() => { lastPassed = true; }, error => { lastFailure = error; }); }, - fail: error => { + fail(error) { lastFailure = error; }, - skip: () => {}, + skip() {}, experiments: {}, ...overwrites, }); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/0-1.cjs b/test-tap/fixture/parallel-runs/custom-comparator/0-1.cjs new file mode 100644 index 000000000..5b1c05662 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/0-1.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '2'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/0-2.cjs b/test-tap/fixture/parallel-runs/custom-comparator/0-2.cjs new file mode 100644 index 000000000..5b1c05662 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/0-2.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '2'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/0-3.cjs b/test-tap/fixture/parallel-runs/custom-comparator/0-3.cjs new file mode 100644 index 000000000..5b1c05662 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/0-3.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '2'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/1-1.cjs b/test-tap/fixture/parallel-runs/custom-comparator/1-1.cjs new file mode 100644 index 000000000..ccb999168 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/1-1.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '1'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/1-2.cjs b/test-tap/fixture/parallel-runs/custom-comparator/1-2.cjs new file mode 100644 index 000000000..ccb999168 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/1-2.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '1'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/1-3.cjs b/test-tap/fixture/parallel-runs/custom-comparator/1-3.cjs new file mode 100644 index 000000000..ccb999168 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/1-3.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '1'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/2-1.cjs b/test-tap/fixture/parallel-runs/custom-comparator/2-1.cjs new file mode 100644 index 000000000..a40e62fb8 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/2-1.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '0'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/2-2.cjs b/test-tap/fixture/parallel-runs/custom-comparator/2-2.cjs new file mode 100644 index 000000000..a40e62fb8 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/2-2.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '0'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/2-3.cjs b/test-tap/fixture/parallel-runs/custom-comparator/2-3.cjs new file mode 100644 index 000000000..a40e62fb8 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/2-3.cjs @@ -0,0 +1,5 @@ +const test = require('../../../../entrypoints/main.cjs'); + +test('at expected index', t => { + t.is(process.env.CI_NODE_INDEX, '0'); +}); diff --git a/test-tap/fixture/parallel-runs/custom-comparator/ava.config.js b/test-tap/fixture/parallel-runs/custom-comparator/ava.config.js new file mode 100644 index 000000000..935e14cf2 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/ava.config.js @@ -0,0 +1,5 @@ +export default { + files: ['*.cjs'], + // Descending order + sortTestFiles: (a, b) => b.localeCompare(a, [], {numeric: true}), +}; diff --git a/test-tap/fixture/parallel-runs/custom-comparator/package.json b/test-tap/fixture/parallel-runs/custom-comparator/package.json new file mode 100644 index 000000000..bedb411a9 --- /dev/null +++ b/test-tap/fixture/parallel-runs/custom-comparator/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test-tap/fixture/sort-tests/0.cjs b/test-tap/fixture/sort-tests/0.cjs new file mode 100644 index 000000000..1af77b598 --- /dev/null +++ b/test-tap/fixture/sort-tests/0.cjs @@ -0,0 +1,5 @@ +const test = require('../../../entrypoints/main.cjs'); + +test('should run third', t => { + t.pass(); +}); diff --git a/test-tap/fixture/sort-tests/1.cjs b/test-tap/fixture/sort-tests/1.cjs new file mode 100644 index 000000000..e1e0ff47b --- /dev/null +++ b/test-tap/fixture/sort-tests/1.cjs @@ -0,0 +1,5 @@ +const test = require('../../../entrypoints/main.cjs'); + +test('should run second', t => { + t.pass(); +}); diff --git a/test-tap/fixture/sort-tests/2.cjs b/test-tap/fixture/sort-tests/2.cjs new file mode 100644 index 000000000..9ad7df09f --- /dev/null +++ b/test-tap/fixture/sort-tests/2.cjs @@ -0,0 +1,5 @@ +const test = require('../../../entrypoints/main.cjs'); + +test('should run first', t => { + t.pass(); +}); diff --git a/test-tap/fixture/sort-tests/ava.config.js b/test-tap/fixture/sort-tests/ava.config.js new file mode 100644 index 000000000..58d098288 --- /dev/null +++ b/test-tap/fixture/sort-tests/ava.config.js @@ -0,0 +1,7 @@ +export default { + files: ['*.cjs'], + // Descending order + sortTestFiles: (a, b) => b.localeCompare(a, [], {numeric: true}), + concurrency: 1, + verbose: true, +}; diff --git a/test-tap/fixture/sort-tests/package.json b/test-tap/fixture/sort-tests/package.json new file mode 100644 index 000000000..bedb411a9 --- /dev/null +++ b/test-tap/fixture/sort-tests/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test-tap/integration/assorted.js b/test-tap/integration/assorted.js index e866824c6..db292e8ac 100644 --- a/test-tap/integration/assorted.js +++ b/test-tap/integration/assorted.js @@ -152,3 +152,11 @@ test('load .js test files as ESM modules', t => { t.end(); }); }); + +test('uses sortTestFiles to sort test files', t => { + execCli([], {dirname: 'fixture/sort-tests'}, (error, stdout) => { + t.error(error); + t.match(stdout, /should run first[\s\S]+?should run second[\s\S]+?should run third/); + t.end(); + }); +}); diff --git a/test-tap/integration/parallel-runs.js b/test-tap/integration/parallel-runs.js index fe30e38c6..47f4c0781 100644 --- a/test-tap/integration/parallel-runs.js +++ b/test-tap/integration/parallel-runs.js @@ -43,3 +43,17 @@ test('fail when there are no files', t => { }, error => t.ok(error)); } }); + +test('correctly applies custom comparator', t => { + t.plan(3); + for (let i = 0; i < 3; i++) { + execCli([], { + dirname: 'fixture/parallel-runs/custom-comparator', + env: { + AVA_FORCE_CI: 'ci', + CI_NODE_INDEX: String(i), + CI_NODE_TOTAL: '3', + }, + }, error => t.error(error)); + } +}); diff --git a/test-tap/reporters/default.edgecases.v17.log b/test-tap/reporters/default.edgecases.v17.log new file mode 100644 index 000000000..e39930d14 --- /dev/null +++ b/test-tap/reporters/default.edgecases.v17.log @@ -0,0 +1,53 @@ + +---tty-stream-chunk-separator + ⚠ Could not parse ast-syntax-error.cjs for line number selection +---tty-stream-chunk-separator + + Uncaught exception in ast-syntax-error.cjs + + SyntaxError: Unexpected token 'do' + +---tty-stream-chunk-separator + ✖ ast-syntax-error.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator + ✖ No tests found in ava-import-no-test-declaration.cjs +---tty-stream-chunk-separator + + Uncaught exception in import-and-use-test-member.cjs + + import-and-use-test-member.cjs:3 + + 2: +  3: test('pass', t => t.pass()); + 4: + + TypeError: test is not a function + + › Object. (test-tap/fixture/report/edgecases/import-and-use-test-member.cjs:3:1) + +---tty-stream-chunk-separator + ✖ import-and-use-test-member.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator + ✖ No tests found in no-ava-import.cjs, make sure to import "ava" at the top of your test file +---tty-stream-chunk-separator + ✖ Line numbers for test.cjs did not match any tests +---tty-stream-chunk-separator + + Uncaught exception in throws.cjs + + throws.cjs:1 + +  1: throw new Error('throws'); + 2: + + Error: throws + + › Object. (test-tap/fixture/report/edgecases/throws.cjs:1:7) + +---tty-stream-chunk-separator + ✖ throws.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator + ─ + + 3 uncaught exceptions +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.failfast.v17.log b/test-tap/reporters/default.failfast.v17.log new file mode 100644 index 000000000..831e81f6c --- /dev/null +++ b/test-tap/reporters/default.failfast.v17.log @@ -0,0 +1,24 @@ + +---tty-stream-chunk-separator + ✖ a › fails Test failed via `t.fail()` +---tty-stream-chunk-separator + ─ + + a › fails + + a.cjs:3 + + 2: +  3: test('fails', t => t.fail()); + 4: + + Test failed via `t.fail()` + + › test-tap/fixture/report/failfast/a.cjs:3:22 + + ─ + + `--fail-fast` is on. 1 test file was skipped. + + 1 test failed +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.failfast2.v17.log b/test-tap/reporters/default.failfast2.v17.log new file mode 100644 index 000000000..22d9cd398 --- /dev/null +++ b/test-tap/reporters/default.failfast2.v17.log @@ -0,0 +1,24 @@ + +---tty-stream-chunk-separator + ✖ a › fails Test failed via `t.fail()` +---tty-stream-chunk-separator + ─ + + a › fails + + a.cjs:3 + + 2: +  3: test('fails', t => t.fail());  + 4: test('passes', t => t.pass()); + + Test failed via `t.fail()` + + › test-tap/fixture/report/failfast2/a.cjs:3:22 + + ─ + + `--fail-fast` is on. At least 1 test was skipped, as well as 1 test file. + + 1 test failed +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.only.v17.log b/test-tap/reporters/default.only.v17.log new file mode 100644 index 000000000..f01706e56 --- /dev/null +++ b/test-tap/reporters/default.only.v17.log @@ -0,0 +1,10 @@ + +---tty-stream-chunk-separator + ✔ a › only +---tty-stream-chunk-separator + ✔ b › passes +---tty-stream-chunk-separator + ─ + + 2 tests passed +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.regular.v17.log b/test-tap/reporters/default.regular.v17.log new file mode 100644 index 000000000..e30d6166f --- /dev/null +++ b/test-tap/reporters/default.regular.v17.log @@ -0,0 +1,361 @@ + +---tty-stream-chunk-separator + Uncaught exception in bad-test-chain.cjs + + bad-test-chain.cjs:3 + + 2: +  3: test.serial.test('passes', t => t.pass()); + 4: + + TypeError: test.serial.test is not a function + + › Object. (test-tap/fixture/report/regular/bad-test-chain.cjs:3:13) + +---tty-stream-chunk-separator + ✖ bad-test-chain.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator + ✖ nested-objects › format with max depth 4 +---tty-stream-chunk-separator + ✖ nested-objects › format like with max depth 4 +---tty-stream-chunk-separator + output-in-hook › before hook + ℹ before +---tty-stream-chunk-separator + output-in-hook › beforeEach hook for passing test + ℹ beforeEach +---tty-stream-chunk-separator + output-in-hook › beforeEach hook for failing test + ℹ beforeEach +---tty-stream-chunk-separator + ✔ output-in-hook › passing test +---tty-stream-chunk-separator + ✖ output-in-hook › failing test Test failed via `t.fail()` +---tty-stream-chunk-separator + output-in-hook › afterEach hook for passing test + ℹ afterEach +---tty-stream-chunk-separator + output-in-hook › afterEach.always hook for failing test + ℹ afterEachAlways +---tty-stream-chunk-separator + output-in-hook › afterEach.always hook for passing test + ℹ afterEachAlways +---tty-stream-chunk-separator + output-in-hook › cleanup + ℹ afterAlways +---tty-stream-chunk-separator + - test › skip +---tty-stream-chunk-separator + - test › todo +---tty-stream-chunk-separator + ✔ test › passes +---tty-stream-chunk-separator + ✖ test › fails Test failed via `t.fail()` +---tty-stream-chunk-separator + ✔ test › known failure +---tty-stream-chunk-separator + ✖ test › no longer failing Test was expected to fail, but succeeded, you should stop marking the test as failing +---tty-stream-chunk-separator + ✖ test › logs Test failed via `t.fail()` + ℹ hello + ℹ world +---tty-stream-chunk-separator + ✖ test › formatted +---tty-stream-chunk-separator + ✖ test › implementation throws non-error Error thrown in test +---tty-stream-chunk-separator + ✖ traces-in-t-throws › throws +---tty-stream-chunk-separator + ✖ traces-in-t-throws › notThrows +---tty-stream-chunk-separator + ✖ traces-in-t-throws › notThrowsAsync +---tty-stream-chunk-separator + ✖ traces-in-t-throws › throwsAsync +---tty-stream-chunk-separator + ✖ traces-in-t-throws › throwsAsync different error +---tty-stream-chunk-separator + ✔ uncaught-exception › passes +---tty-stream-chunk-separator + + Uncaught exception in uncaught-exception.cjs + + uncaught-exception.cjs:5 + + 4: setImmediate(() => { +  5: throw new Error('Can’t catch me'); + 6: }); + + Error: Can’t catch me + + › Immediate. (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) + +---tty-stream-chunk-separator + ✖ uncaught-exception.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator + ✔ unhandled-rejection › passes +---tty-stream-chunk-separator + ✔ unhandled-rejection › unhandled non-error rejection +---tty-stream-chunk-separator + + Unhandled rejection in unhandled-rejection.cjs + + unhandled-rejection.cjs:4 + + 3: const passes = t => { +  4: Promise.reject(new Error('Can’t catch me')); + 5: t.pass(); + + Error: Can’t catch me + + › passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17) + +---tty-stream-chunk-separator + Unhandled rejection in unhandled-rejection.cjs + + null + +---tty-stream-chunk-separator + ─ + + nested-objects › format with max depth 4 + + nested-objects.cjs:29 + + 28: }; +  29: t.deepEqual(exp, act); + 30: }); + + Difference: + + { + a: { + b: { + foo: 'bar', + }, + }, + + c: { + + d: { + + e: { + + foo: 'bar', + + }, + + }, + + }, + } + + › test-tap/fixture/report/regular/nested-objects.cjs:29:4 + + + + nested-objects › format like with max depth 4 + + nested-objects.cjs:55 + + 54: }; +  55: t.like(actual, pattern); + 56: }); + + Difference: + + { + a: { + b: { + - foo: 'bar', + + foo: 'qux', + }, + }, + } + + › test-tap/fixture/report/regular/nested-objects.cjs:55:4 + + + + output-in-hook › failing test + + output-in-hook.cjs:34 + + 33: test('failing test', t => { +  34: t.fail();  + 35: }); + + Test failed via `t.fail()` + + › test-tap/fixture/report/regular/output-in-hook.cjs:34:4 + + + + test › fails + + test.cjs:9 + + 8: +  9: test('fails', t => t.fail()); + 10: + + Test failed via `t.fail()` + + › test-tap/fixture/report/regular/test.cjs:9:22 + + + + test › no longer failing + + Error: Test was expected to fail, but succeeded, you should stop marking the test as failing + + + + test › logs + + ℹ hello + ℹ world + + test.cjs:18 + + 17: t.log('world'); +  18: t.fail();  + 19: }); + + Test failed via `t.fail()` + + › test-tap/fixture/report/regular/test.cjs:18:4 + + + + test › formatted + + test.cjs:22 + + 21: test('formatted', t => { +  22: t.deepEqual('foo', 'bar'); + 23: }); + + Difference: + + - 'foo' + + 'bar' + + › test-tap/fixture/report/regular/test.cjs:22:4 + + + + test › implementation throws non-error + + Error thrown in test: + + null + + + + traces-in-t-throws › throws + + traces-in-t-throws.cjs:12 + + 11: test('throws', t => { +  12: t.throws(() => throwError(), {instanceOf: TypeError}); + 13: }); + + Function threw unexpected exception: + + Error { + message: 'uh-oh', + } + + Expected instance of: + + Function TypeError {} + + › throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + › t.throws.instanceOf (test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:17) + › test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 + + + + traces-in-t-throws › notThrows + + traces-in-t-throws.cjs:16 + + 15: test('notThrows', t => { +  16: t.notThrows(() => throwError()); + 17: }); + + Function threw: + + Error { + message: 'uh-oh', + } + + › throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + › test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:20 + › test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 + + + + traces-in-t-throws › notThrowsAsync + + traces-in-t-throws.cjs:20 + + 19: test('notThrowsAsync', t => { +  20: t.notThrowsAsync(() => throwError()); + 21: }); + + Function threw: + + Error { + message: 'uh-oh', + } + + › throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + › test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:25 + › test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 + + + + traces-in-t-throws › throwsAsync + + traces-in-t-throws.cjs:24 + + 23: test('throwsAsync', t => { +  24: t.throwsAsync(() => throwError(), {instanceOf: TypeError}); + 25: }); + + Function threw synchronously. Use `t.throws()` instead: + + Error { + message: 'uh-oh', + } + + › throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + › t.throwsAsync.instanceOf (test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:22) + › test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 + + + + traces-in-t-throws › throwsAsync different error + + traces-in-t-throws.cjs:27 + + 26: +  27: test('throwsAsync different error', t => t.throwsAsync(returnRejectedPromise, {instanceOf: TypeError})); + 28: + + Returned promise rejected with unexpected exception: + + Error { + message: 'uh-oh', + } + + Expected instance of: + + Function TypeError {} + + › returnRejectedPromise (test-tap/fixture/report/regular/traces-in-t-throws.cjs:8:24) + › test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 + + ─ + + 13 tests failed + 1 known failure + 1 test skipped + 1 test todo + 2 unhandled rejections + 2 uncaught exceptions +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.timeoutinmultiplefiles.v17.log b/test-tap/reporters/default.timeoutinmultiplefiles.v17.log new file mode 100644 index 000000000..dbc999ffd --- /dev/null +++ b/test-tap/reporters/default.timeoutinmultiplefiles.v17.log @@ -0,0 +1,33 @@ + +---tty-stream-chunk-separator + ✔ a › a passes +---tty-stream-chunk-separator + ✔ a › a passes two +---tty-stream-chunk-separator +  + ✖ Timed out while running tests + + 2 tests were pending in a.cjs + + ◌ a › a slow + ◌ a › a slow two + +---tty-stream-chunk-separator + ✔ b › b passes +---tty-stream-chunk-separator + ✔ b › b passes two +---tty-stream-chunk-separator +  + ✖ Timed out while running tests + + 3 tests were pending in b.cjs + + ◌ b › b slow + ◌ b › b slow two + ◌ b › b slow three + +---tty-stream-chunk-separator + ─ + + 4 tests passed +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.timeoutinsinglefile.v17.log b/test-tap/reporters/default.timeoutinsinglefile.v17.log new file mode 100644 index 000000000..43c2cbffa --- /dev/null +++ b/test-tap/reporters/default.timeoutinsinglefile.v17.log @@ -0,0 +1,19 @@ + +---tty-stream-chunk-separator + ✔ passes +---tty-stream-chunk-separator + ✔ passes two +---tty-stream-chunk-separator +  + ✖ Timed out while running tests + + 2 tests were pending in a.cjs + + ◌ slow + ◌ slow two + +---tty-stream-chunk-separator + ─ + + 2 tests passed +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.timeoutwithmatch.v17.log b/test-tap/reporters/default.timeoutwithmatch.v17.log new file mode 100644 index 000000000..e64e4e60f --- /dev/null +++ b/test-tap/reporters/default.timeoutwithmatch.v17.log @@ -0,0 +1,17 @@ + +---tty-stream-chunk-separator + ✔ passes needle +---tty-stream-chunk-separator +  + ✖ Timed out while running tests + + 2 tests were pending in a.cjs + + ◌ slow needle + ◌ slow three needle + +---tty-stream-chunk-separator + ─ + + 1 test passed +---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.watch.v17.log b/test-tap/reporters/default.watch.v17.log new file mode 100644 index 000000000..ae2dea44b --- /dev/null +++ b/test-tap/reporters/default.watch.v17.log @@ -0,0 +1,32 @@ + +---tty-stream-chunk-separator + ✔ test › passes +---tty-stream-chunk-separator + ─ + + 1 test passed [17:19:12] + +---tty-stream-chunk-separator +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +---tty-stream-chunk-separator + +---tty-stream-chunk-separator + ✔ test › passes +---tty-stream-chunk-separator + ─ + + 1 test passed [17:19:12] + 2 previous failures in test files that were not rerun + +---tty-stream-chunk-separator +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +---tty-stream-chunk-separator + +---tty-stream-chunk-separator + ✔ test › passes +---tty-stream-chunk-separator + ─ + + 1 test passed [17:19:12] + +---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.edgecases.v17.log b/test-tap/reporters/tap.edgecases.v17.log new file mode 100644 index 000000000..ba4f57781 --- /dev/null +++ b/test-tap/reporters/tap.edgecases.v17.log @@ -0,0 +1,42 @@ +TAP version 13 +---tty-stream-chunk-separator +not ok 1 - SyntaxError: Unexpected token 'do' + --- + name: SyntaxError + message: Unexpected token 'do' + at: '' + ... +---tty-stream-chunk-separator +not ok 2 - ast-syntax-error.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator +not ok 3 - No tests found in ava-import-no-test-declaration.cjs +---tty-stream-chunk-separator +not ok 4 - TypeError: test is not a function + --- + name: TypeError + message: test is not a function + at: >- + Object. + (test-tap/fixture/report/edgecases/import-and-use-test-member.cjs:3:1) + ... +---tty-stream-chunk-separator +not ok 5 - import-and-use-test-member.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator +not ok 6 - No tests found in no-ava-import.cjs, make sure to import "ava" at the top of your test file +---tty-stream-chunk-separator +not ok 7 - Error: throws + --- + name: Error + message: throws + at: 'Object. (test-tap/fixture/report/edgecases/throws.cjs:1:7)' + ... +---tty-stream-chunk-separator +not ok 8 - throws.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator + +1..0 +# tests 0 +# pass 0 +# fail 8 + +---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.failfast.v17.log b/test-tap/reporters/tap.failfast.v17.log new file mode 100644 index 000000000..5b44649f1 --- /dev/null +++ b/test-tap/reporters/tap.failfast.v17.log @@ -0,0 +1,17 @@ +TAP version 13 +---tty-stream-chunk-separator +not ok 1 - a › fails + --- + name: AssertionError + message: Test failed via `t.fail()` + assertion: fail + at: 'test-tap/fixture/report/failfast/a.cjs:3:22' + ... +---tty-stream-chunk-separator + +1..1 +# tests 1 +# pass 0 +# fail 1 + +---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.failfast2.v17.log b/test-tap/reporters/tap.failfast2.v17.log new file mode 100644 index 000000000..c10c8cd9f --- /dev/null +++ b/test-tap/reporters/tap.failfast2.v17.log @@ -0,0 +1,19 @@ +TAP version 13 +---tty-stream-chunk-separator +not ok 1 - a › fails + --- + name: AssertionError + message: Test failed via `t.fail()` + assertion: fail + at: 'test-tap/fixture/report/failfast2/a.cjs:3:22' + ... +---tty-stream-chunk-separator +# 1 test remaining in a.cjs +---tty-stream-chunk-separator + +1..2 +# tests 2 +# pass 0 +# fail 2 + +---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.only.v17.log b/test-tap/reporters/tap.only.v17.log new file mode 100644 index 000000000..36f42b988 --- /dev/null +++ b/test-tap/reporters/tap.only.v17.log @@ -0,0 +1,13 @@ +TAP version 13 +---tty-stream-chunk-separator +ok 1 - a › only +---tty-stream-chunk-separator +ok 2 - b › passes +---tty-stream-chunk-separator + +1..2 +# tests 2 +# pass 2 +# fail 0 + +---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.regular.v17.log b/test-tap/reporters/tap.regular.v17.log new file mode 100644 index 000000000..c0379a149 --- /dev/null +++ b/test-tap/reporters/tap.regular.v17.log @@ -0,0 +1,268 @@ +TAP version 13 +---tty-stream-chunk-separator +not ok 1 - TypeError: test.serial.test is not a function + --- + name: TypeError + message: test.serial.test is not a function + at: 'Object. (test-tap/fixture/report/regular/bad-test-chain.cjs:3:13)' + ... +---tty-stream-chunk-separator +not ok 2 - bad-test-chain.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator +not ok 3 - nested-objects › format with max depth 4 + --- + name: AssertionError + assertion: deepEqual + values: + 'Difference:': |2- + { + a: { + b: { + foo: 'bar', + }, + }, + + c: { + + d: { + + e: { + + foo: 'bar', + + }, + + }, + + }, + } + at: 'test-tap/fixture/report/regular/nested-objects.cjs:29:4' + ... +---tty-stream-chunk-separator +not ok 4 - nested-objects › format like with max depth 4 + --- + name: AssertionError + assertion: like + values: + 'Difference:': |2- + { + a: { + b: { + - foo: 'bar', + + foo: 'qux', + }, + }, + } + at: 'test-tap/fixture/report/regular/nested-objects.cjs:55:4' + ... +---tty-stream-chunk-separator +# output-in-hook › before hook +---tty-stream-chunk-separator +# output-in-hook › before hook +---tty-stream-chunk-separator +# before +---tty-stream-chunk-separator +# output-in-hook › beforeEach hook for passing test +---tty-stream-chunk-separator +# beforeEach +---tty-stream-chunk-separator +# output-in-hook › beforeEach hook for failing test +---tty-stream-chunk-separator +# beforeEach +---tty-stream-chunk-separator +ok 5 - output-in-hook › passing test +---tty-stream-chunk-separator +not ok 6 - output-in-hook › failing test + --- + name: AssertionError + message: Test failed via `t.fail()` + assertion: fail + at: 'test-tap/fixture/report/regular/output-in-hook.cjs:34:4' + ... +---tty-stream-chunk-separator +# output-in-hook › afterEach hook for passing test +---tty-stream-chunk-separator +# afterEach +---tty-stream-chunk-separator +# output-in-hook › afterEach.always hook for failing test +---tty-stream-chunk-separator +# afterEachAlways +---tty-stream-chunk-separator +# output-in-hook › afterEach.always hook for passing test +---tty-stream-chunk-separator +# afterEachAlways +---tty-stream-chunk-separator +# output-in-hook › cleanup +---tty-stream-chunk-separator +# afterAlways +---tty-stream-chunk-separator +ok 7 - test › skip # SKIP +---tty-stream-chunk-separator +not ok 8 - test › todo # TODO +---tty-stream-chunk-separator +ok 9 - test › passes +---tty-stream-chunk-separator +not ok 10 - test › fails + --- + name: AssertionError + message: Test failed via `t.fail()` + assertion: fail + at: 'test-tap/fixture/report/regular/test.cjs:9:22' + ... +---tty-stream-chunk-separator +ok 11 - test › known failure +---tty-stream-chunk-separator +not ok 12 - test › no longer failing + --- + name: Error + message: >- + Test was expected to fail, but succeeded, you should stop marking the test as + failing + at: '' + ... +---tty-stream-chunk-separator +not ok 13 - test › logs +# hello +# world + --- + name: AssertionError + message: Test failed via `t.fail()` + assertion: fail + at: 'test-tap/fixture/report/regular/test.cjs:18:4' + ... +---tty-stream-chunk-separator +not ok 14 - test › formatted + --- + name: AssertionError + assertion: deepEqual + values: + 'Difference:': |- + - 'foo' + + 'bar' + at: 'test-tap/fixture/report/regular/test.cjs:22:4' + ... +---tty-stream-chunk-separator +not ok 15 - test › implementation throws non-error + --- + name: AssertionError + message: Error thrown in test + values: + 'Error thrown in test:': 'null' + at: '' + ... +---tty-stream-chunk-separator +not ok 16 - traces-in-t-throws › throws + --- + name: AssertionError + assertion: throws + values: + 'Function threw unexpected exception:': |- + Error { + message: 'uh-oh', + } + 'Expected instance of:': 'Function TypeError {}' + at: >- + throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + + t.throws.instanceOf + (test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:17) + + test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 + ... +---tty-stream-chunk-separator +not ok 17 - traces-in-t-throws › notThrows + --- + name: AssertionError + assertion: notThrows + values: + 'Function threw:': |- + Error { + message: 'uh-oh', + } + at: |- + throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:20 + test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 + ... +---tty-stream-chunk-separator +not ok 18 - traces-in-t-throws › notThrowsAsync + --- + name: AssertionError + assertion: notThrowsAsync + values: + 'Function threw:': |- + Error { + message: 'uh-oh', + } + at: |- + throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:25 + test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 + ... +---tty-stream-chunk-separator +not ok 19 - traces-in-t-throws › throwsAsync + --- + name: AssertionError + assertion: throwsAsync + values: + 'Function threw synchronously. Use `t.throws()` instead:': |- + Error { + message: 'uh-oh', + } + at: >- + throwError (test-tap/fixture/report/regular/traces-in-t-throws.cjs:4:8) + + t.throwsAsync.instanceOf + (test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:22) + + test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 + ... +---tty-stream-chunk-separator +not ok 20 - traces-in-t-throws › throwsAsync different error + --- + name: AssertionError + assertion: throwsAsync + values: + 'Returned promise rejected with unexpected exception:': |- + Error { + message: 'uh-oh', + } + 'Expected instance of:': 'Function TypeError {}' + at: >- + returnRejectedPromise + (test-tap/fixture/report/regular/traces-in-t-throws.cjs:8:24) + + test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 + ... +---tty-stream-chunk-separator +ok 21 - uncaught-exception › passes +---tty-stream-chunk-separator +not ok 22 - Error: Can’t catch me + --- + name: Error + message: Can’t catch me + at: >- + Immediate. + (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) + ... +---tty-stream-chunk-separator +not ok 23 - uncaught-exception.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator +ok 24 - unhandled-rejection › passes +---tty-stream-chunk-separator +ok 25 - unhandled-rejection › unhandled non-error rejection +---tty-stream-chunk-separator +not ok 26 - Error: Can’t catch me + --- + name: Error + message: Can’t catch me + at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17)' + ... +---tty-stream-chunk-separator +not ok 27 - unhandled-rejection + --- + message: Non-error object + formatted: 'null' + ... +---tty-stream-chunk-separator + +1..21 +# tests 20 +# pass 6 +# skip 1 +# fail 20 + +---tty-stream-chunk-separator diff --git a/test-tap/test.js b/test-tap/test.js index 60c5834ed..c1c89b457 100644 --- a/test-tap/test.js +++ b/test-tap/test.js @@ -429,7 +429,9 @@ test('failing tests must not return a fulfilled promise', t => ava.failing(a => test('failing tests pass when returning a rejected promise', t => ava.failing(a => { a.plan(1); - return a.notThrowsAsync(delay(10), {value: 'foo'}).then(() => Promise.reject()); + return a.notThrowsAsync(delay(10), {value: 'foo'}).then(() => { + throw new Error('reject'); + }); }).run().then(result => { t.equal(result.passed, true); })); diff --git a/test/config/fixtures/unsupported-configs/ava.config.js b/test/config/fixtures/unsupported-configs/ava.config.js new file mode 100644 index 000000000..4a9fb4c27 --- /dev/null +++ b/test/config/fixtures/unsupported-configs/ava.config.js @@ -0,0 +1,3 @@ +export default { + failFast: true, +}; diff --git a/test/config/fixtures/unsupported-configs/ava.config.json b/test/config/fixtures/unsupported-configs/ava.config.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/config/fixtures/unsupported-configs/ava.config.json @@ -0,0 +1 @@ +{} diff --git a/test/config/fixtures/unsupported-configs/package.json b/test/config/fixtures/unsupported-configs/package.json new file mode 100644 index 000000000..bedb411a9 --- /dev/null +++ b/test/config/fixtures/unsupported-configs/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/config/loader.js b/test/config/loader.js index 1be2d0ec7..8f4c5ae54 100644 --- a/test/config/loader.js +++ b/test/config/loader.js @@ -10,13 +10,15 @@ const FIXTURE_ROOT = fileURLToPath(new URL('../../test-tap/fixture/load-config', const resolve = relpath => path.resolve(FIXTURE_ROOT, relpath); -const loadFromSetup = setup => { +const loadFromSetup = async setup => { if (typeof setup === 'string') { - return loadConfig(); + const loaded = await loadConfig(); + return loaded.config; } const {configFile, defaults, resolveFrom} = setup; - return loadConfig({configFile, defaults, resolveFrom}); + const loaded = await loadConfig({configFile, defaults, resolveFrom}); + return loaded.config; }; const ok = setup => async (t, assert = tt => tt.pass()) => { diff --git a/test/config/next-gen.js b/test/config/next-gen.js index 5e62efd21..2bcf4b872 100644 --- a/test/config/next-gen.js +++ b/test/config/next-gen.js @@ -10,23 +10,31 @@ const FIXTURE_ROOT = fileURLToPath(new URL('fixtures', import.meta.url)); const resolve = relpath => path.resolve(FIXTURE_ROOT, relpath); -const loadFromSetup = setup => { +const loadFromSetup = async (setup, t, assertUnsupportedFiles = (tt, files) => tt.is(files.length, 0)) => { if (typeof setup === 'string') { - return loadConfig(); + const loaded = await loadConfig(); + return loaded.config; } - const {configFile, defaults, resolveFrom} = setup; - return loadConfig({configFile, defaults, resolveFrom}); + const { + configFile, + defaults, + resolveFrom, + } = setup; + + const loaded = await loadConfig({configFile, defaults, resolveFrom}); + assertUnsupportedFiles(t, loaded.unsupportedFiles); + return loaded.config; }; -const ok = setup => async (t, assert = tt => tt.pass()) => { +const ok = setup => async (t, assert = tt => tt.pass(), assertUnsupportedFiles = undefined) => { const fixture = typeof setup === 'string' ? setup : setup.fixture; const stub = sinon.stub(process, 'cwd'); t.teardown(() => stub.restore()); stub.returns(resolve(fixture)); - const conf = loadFromSetup(setup); + const conf = loadFromSetup(setup, t, assertUnsupportedFiles); await t.notThrowsAsync(conf); const result = await t.try(assert, await conf, setup); result.commit(); @@ -39,7 +47,7 @@ const notOk = setup => async (t, assert = (tt, error) => tt.snapshot(error.messa t.teardown(() => stub.restore()); stub.returns(resolve(fixture)); - const conf = loadFromSetup(setup); + const conf = loadFromSetup(setup, t); const error = await t.throwsAsync(conf); const result = await t.try(assert, error, setup); result.commit(); @@ -67,6 +75,19 @@ test.serial('loads .js config as ESM', ok('js-as-esm'), (t, conf) => { t.true(conf.failFast); }); +test.serial('finds unsupported configs', + ok({ + fixture: 'unsupported-configs', + }), + (t, conf) => { + t.true(conf.failFast); + }, + (t, unsupportedFiles) => { + t.is(unsupportedFiles.length, 1); + t.regex(unsupportedFiles[0], /ava\.config\.json/); + }, +); + test.serial('handles errors when loading .js config as ESM', notOk({ fixture: 'js-as-esm', configFile: 'error.js', diff --git a/test/helpers/simulate-tty.cjs b/test/helpers/simulate-tty.cjs index 7b75aa997..c37f102c3 100644 --- a/test/helpers/simulate-tty.cjs +++ b/test/helpers/simulate-tty.cjs @@ -6,7 +6,7 @@ const assertHasColorsArguments = count => { tty.WriteStream.prototype.hasColors(count); }; -const makeHasColors = colorDepth => (count = 16, env) => { // eslint-disable-line default-param-last +const makeHasColors = colorDepth => (count = 16, env) => { // `count` is optional too, so make sure it's not an env object. if (env === undefined && typeof count === 'object' && count !== null) { count = 16; diff --git a/test/node_modules/.bin/test-ava b/test/node_modules/.bin/test-ava deleted file mode 120000 index bd4f1e8fb..000000000 --- a/test/node_modules/.bin/test-ava +++ /dev/null @@ -1 +0,0 @@ -/Users/jsamines/dev/personal/ava/node_modules/.bin/test-ava \ No newline at end of file diff --git a/test/snapshot-removal/test.js b/test/snapshot-removal/test.js index b56a891cd..3d43ff271 100644 --- a/test/snapshot-removal/test.js +++ b/test/snapshot-removal/test.js @@ -100,7 +100,7 @@ test.serial('snapshots remain if tests run with --match', testSnapshotPruning, { cwd: cwd('removal'), cli: ['--update-snapshots', '--match=\'*another*\''], remove: false, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); const result = await run; t.snapshot(result.stats.passed, 'passed tests'); @@ -111,7 +111,7 @@ test.serial('snapshots removed if --match selects all tests', testSnapshotPrunin cwd: cwd('removal'), cli: ['--update-snapshots', '--match=\'*snapshot*\''], remove: true, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); const result = await run; t.snapshot(result.stats.passed, 'passed tests'); @@ -122,7 +122,7 @@ test.serial('snapshots remain if tests selected by line numbers', testSnapshotPr cwd: cwd('removal'), cli: ['test.js:10-17', '--update-snapshots'], remove: false, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); const result = await run; t.snapshot(result.stats.passed, 'passed tests'); @@ -133,7 +133,7 @@ test.serial('snapshots removed if line numbers select all tests', testSnapshotPr cwd: cwd('removal'), cli: ['test.js:0-100', '--update-snapshots'], remove: true, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); const result = await run; t.snapshot(result.stats.passed, 'passed tests'); @@ -144,7 +144,7 @@ test.serial('snapshots remain if using test.only', testSnapshotPruning, { cwd: cwd('only-test'), cli: ['--update-snapshots'], remove: false, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); }, }); @@ -153,7 +153,7 @@ test.serial('snapshots remain if tests are skipped', testSnapshotPruning, { cwd: cwd('skipped-tests'), cli: ['--update-snapshots'], remove: false, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); }, }); @@ -162,7 +162,7 @@ test.serial('snapshots remain if snapshot assertions are skipped', testSnapshotP cwd: cwd('skipped-snapshots'), cli: ['--update-snapshots'], remove: false, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); }, }); @@ -181,7 +181,7 @@ test.serial('snapshots removed if skipped in a discarded try()', testSnapshotPru cwd: cwd('skipped-snapshots-in-try'), cli: ['--update-snapshots'], remove: true, - checkRun: async (t, run) => { + async checkRun(t, run) { await t.notThrowsAsync(run, 'Expected fixture not to throw'); }, }); diff --git a/types/assertions.d.ts b/types/assertions.d.ts index 657ed3d48..ce5a97a14 100644 --- a/types/assertions.d.ts +++ b/types/assertions.d.ts @@ -138,6 +138,18 @@ export interface DeepEqualAssertion { */ (actual: Actual, expected: Expected, message?: string): actual is Expected; + /** + * Assert that `actual` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): expected is Actual; + + /** + * Assert that `actual` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): boolean; + /** Skip this assertion. */ skip(actual: any, expected: any, message?: string): void; }