Remove built-in Babel support
This updates code and tests to remove built-in Babel support. In the future, it needs to be opted in to, and @ava/babel needs to be installed besides AVA itself. Our tests have become quite muddled, and some of them require Babel to still be enabled, but that's all OK for now. * Remove outdated JSPM recipe * Update documentation to reflect the removal of built-in Babel * Move responsibility for power-assert to @ava/babel
This commit is contained in:
parent
4953457277
commit
b4ea43529a
227 changed files with 868 additions and 2377 deletions
|
|
@ -28,7 +28,6 @@ The [`question` label](https://github.com/avajs/ava/labels/question) is a good p
|
|||
|
||||
You can use issue labels to discover issues you could help out with:
|
||||
|
||||
* [`babel` issues](https://github.com/avajs/ava/labels/babel) relate to our Babel infrastructure
|
||||
* [`blocked` issues](https://github.com/avajs/ava/labels/blocked) need help getting unstuck
|
||||
* [`bug` issues](https://github.com/avajs/ava/labels/bug) are known bugs we'd like to fix
|
||||
* [`enhancement` issues](https://github.com/avajs/ava/labels/enhancement) are features we're open to including
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ AVA tries to run test files with their current working directory set to the dire
|
|||
|
||||
Each test file is run in a separate Node.js process. This allows you to change the global state or overriding a built-in in one test file, without affecting another. It's also great for performance on modern multi-core processors, allowing multiple test files to execute in parallel.
|
||||
|
||||
AVA will set `process.env.NODE_ENV` to `test`, unless the `NODE_ENV` environment variable has been set. This is useful if the code you're testing has test defaults (for example when picking what database to connect to, or environment-specific Babel options). It may cause your code or its dependencies to behave differently though. Note that `'NODE_ENV' in process.env` will always be `true`.
|
||||
AVA will set `process.env.NODE_ENV` to `test`, unless the `NODE_ENV` environment variable has been set. This is useful if the code you're testing has test defaults (for example when picking what database to connect to). It may cause your code or its dependencies to behave differently though. Note that `'NODE_ENV' in process.env` will always be `true`.
|
||||
|
||||
## Declaring tests
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ test('skip assertion', t => {
|
|||
|
||||
## Enhanced assertion messages
|
||||
|
||||
AVA comes with [`power-assert`](https://github.com/power-assert-js/power-assert) built-in, giving you more descriptive assertion messages.
|
||||
Enabling [Babel](./recipes/babel.md) will also enable [`power-assert`](https://github.com/power-assert-js/power-assert), giving you more descriptive assertion messages.
|
||||
|
||||
Let's take this example, using Node's standard [`assert` library](https://nodejs.org/api/assert.html):
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,13 @@ test(function foo(t) {
|
|||
|
||||
## Resetting AVA's cache
|
||||
|
||||
AVA caches the compiled test and helper files. It automatically recompiles these files when you change them. AVA tries its best to detect changes to your Babel configuration files, plugins and presets. If it seems like your latest Babel configuration isn't being applied, however, you can run AVA with the `--reset-cache` flag to reset AVA's cache. If set, all files in the `node_modules/.cache/ava` directory are deleted. Run AVA as normal to apply your new Babel configuration.
|
||||
AVA may cache certain files, especially when you use our [`@ava/babel`](https://github.com/avajs/babel) provider. If it seems like your latest changes aren't being picked up by AVA you can reset the cache by running:
|
||||
|
||||
```console
|
||||
npx ava reset-cache
|
||||
```
|
||||
|
||||
This deletes all files in the `node_modules/.cache/ava` directory.
|
||||
|
||||
## Reporters
|
||||
|
||||
|
|
|
|||
|
|
@ -26,25 +26,16 @@ To ignore files, prefix the pattern with an `!` (exclamation mark).
|
|||
"*oo",
|
||||
"!foo"
|
||||
],
|
||||
"cache": true,
|
||||
"concurrency": 5,
|
||||
"failFast": true,
|
||||
"failWithoutAssertions": false,
|
||||
"environmentVariables": {
|
||||
"MY_ENVIRONMENT_VARIABLE": "some value"
|
||||
},
|
||||
"tap": true,
|
||||
"verbose": true,
|
||||
"compileEnhancements": false,
|
||||
"require": [
|
||||
"@babel/register"
|
||||
],
|
||||
"babel": {
|
||||
"extensions": ["js", "jsx"],
|
||||
"testOptions": {
|
||||
"babelrc": false
|
||||
}
|
||||
}
|
||||
"./my-helper-module.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -53,8 +44,8 @@ Arguments passed to the CLI will always take precedence over the CLI options con
|
|||
|
||||
## Options
|
||||
|
||||
- `files`: an array of glob patterns to select test files. Files with an underscore prefix are ignored. By default only selects files with `js` extensions, even if the pattern matches other files. Specify `extensions` and `babel.extensions` to allow other file extensions
|
||||
- `helpers`: an array of glob patterns to select helper files. Files matched here are never considered as tests. By default only selects files with `js` extensions, even if the pattern matches other files. Specify `extensions` and `babel.extensions` to allow other file extensions
|
||||
- `files`: an array of glob patterns to select test files. Files with an underscore prefix are ignored. By default only selects files with `js` extensions, even if the pattern matches other files. Specify `extensions` to allow other file extensions
|
||||
- `helpers`: an array of glob patterns to select helper files. Files matched here are never considered as tests. By default only selects files with `js` extensions, even if the pattern matches other files. Specify `extensions` to allow other file extensions
|
||||
- `sources`: an array of glob patterns to match files that, when changed, cause tests to be re-run (when in watch mode). See the [watch mode recipe for details](https://github.com/avajs/ava/blob/master/docs/recipes/watch-mode.md#source-files-and-test-files)
|
||||
- `match`: not typically useful in the `package.json` configuration, but equivalent to [specifying `--match` on the CLI](./05-command-line.md#running-tests-with-matching-titles)
|
||||
- `cache`: cache compiled test and helper files under `node_modules/.cache/ava`. If `false`, files are cached in a temporary directory instead
|
||||
|
|
@ -64,15 +55,14 @@ Arguments passed to the CLI will always take precedence over the CLI options con
|
|||
- `tap`: if `true`, enables the [TAP reporter](./05-command-line.md#tap-reporter)
|
||||
- `verbose`: if `true`, enables verbose output
|
||||
- `snapshotDir`: specifies a fixed location for storing snapshot files. Use this if your snapshots are ending up in the wrong location
|
||||
- `compileEnhancements`: if `false`, disables [`power-assert`](./03-assertions.md#enhanced-assertion-messages) — which otherwise helps provide more descriptive error messages — and detection of improper use of the `t.throws()` assertion
|
||||
- `extensions`: extensions of test files that are not precompiled using AVA's Babel presets. Note that files are still compiled to enable `power-assert` and other features, so you may also need to set `compileEnhancements` to `false` if your files are not valid JavaScript. Setting this overrides the default `"js"` value, so make sure to include that extension in the list, as long as it's not included in `babel.extensions`
|
||||
- `extensions`: extensions of test files. Setting this overrides the default `"js"` value, so make sure to include that extension in the list
|
||||
- `require`: extra modules to require before tests are run. Modules are required in the [worker processes](./01-writing-tests.md#process-isolation)
|
||||
- `babel`: test file specific Babel options. See our [Babel recipe](./recipes/babel.md#configuring-babel) for more details
|
||||
- `babel.extensions`: extensions of test files that will be precompiled using AVA's Babel presets. Setting this overrides the default `"js"` value, so make sure to include that extension in the list
|
||||
- `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.
|
||||
|
||||
Note that providing files on the CLI overrides the `files` option.
|
||||
|
||||
Provide the `babel` option (and install [`@ava/babel`](https://github.com/avajs/babel) as an additional dependency) to enable Babel compilation.
|
||||
|
||||
## Using `ava.config.js`
|
||||
|
||||
To use an `ava.config.js` file:
|
||||
|
|
|
|||
|
|
@ -4,14 +4,6 @@ Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/do
|
|||
|
||||
If you use [ESLint](http://eslint.org/), you can install [eslint-plugin-ava](https://github.com/avajs/eslint-plugin-ava). It will help you use AVA correctly and avoid some common pitfalls.
|
||||
|
||||
## Transpiling imported modules
|
||||
|
||||
AVA currently only transpiles test and helper files. *It will not transpile modules you `import` from outside of the test.* This may be unexpected but there are workarounds.
|
||||
|
||||
If you use Babel you can use its [require hook](https://babeljs.io/docs/usage/require/) to transpile imported modules on-the-fly. To add it, [configure it in your `package.json`](./06-configuration.md).
|
||||
|
||||
You can also transpile your modules in a separate process and refer to the transpiled files rather than the sources from your tests.
|
||||
|
||||
## AVA in Docker
|
||||
|
||||
If you run AVA in Docker as part of your CI, you need to fix the appropriate environment variables. Specifically, adding `-e CI=true` in the `docker exec` command. See [#751](https://github.com/avajs/ava/issues/751).
|
||||
|
|
@ -81,6 +73,8 @@ test('one is one', t => {
|
|||
});
|
||||
```
|
||||
|
||||
Also make sure to enable [Babel](./recipes/babel.md).
|
||||
|
||||
## Sharing variables between asynchronous tests
|
||||
|
||||
By default AVA executes tests concurrently. This can cause problems if your tests are asynchronous and share variables.
|
||||
|
|
|
|||
|
|
@ -2,285 +2,18 @@
|
|||
|
||||
Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/docs/recipes/babel.md)
|
||||
|
||||
AVA uses [Babel 7](https://babeljs.io) so you can use the latest JavaScript syntax in your tests. We do this by compiling test and helper files using our [`@ava/stage-4`](https://github.com/avajs/babel-preset-stage-4) preset. We also use a [second preset, `@ava/transform-test-files`](https://github.com/avajs/babel-preset-transform-test-files) to enable [enhanced assertion messages](../03-assertions.md#enhanced-assertion-messages) and detect improper use of `t.throws()` assertions.
|
||||
**The upcoming AVA 3 release removes built-in Babel support. See the [AVA 2](https://github.com/avajs/ava/blob/v2.4.0/docs/recipes/babel.md) documentation instead.**
|
||||
|
||||
By default our Babel pipeline is applied to test and helper files ending in `.js`. If your project uses Babel then we'll automatically compile these files using your project's Babel configuration. The `@ava/transform-helper-files` preset is applied first, and the `@ava/stage-4` last.
|
||||
|
||||
If you are using Babel for your source files then you must also [configure source compilation](#compile-sources).
|
||||
|
||||
## Customize how AVA compiles your test files
|
||||
|
||||
You can override the default Babel configuration AVA uses for test file compilation in `package.json` or `ava.config.js`. For example, the configuration below adds support for JSX syntax and stage 3 features.
|
||||
You can enable Babel support by installing `@ava/babel`, and then in AVA's configuration setting `babel` to `true`:
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"testOptions": {
|
||||
"plugins": ["@babel/plugin-syntax-jsx"],
|
||||
"presets": ["@babel/preset-stage-3"]
|
||||
}
|
||||
}
|
||||
"babel": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
All [Babel options] are allowed inside the `testOptions` object.
|
||||
|
||||
## Reset AVA's cache
|
||||
|
||||
AVA caches the compiled test and helper files. It automatically recompiles these files when you change them. AVA tries its best to detect changes to your Babel configuration files, plugins and presets. If it seems like your latest Babel configuration isn't being applied, however, you can reset AVA's cache:
|
||||
|
||||
```console
|
||||
$ npx ava --reset-cache
|
||||
```
|
||||
|
||||
## Add additional extensions
|
||||
|
||||
You can configure AVA to recognize additional file extensions and compile those test & helper files using Babel.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"extensions": [
|
||||
"js",
|
||||
"jsx"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See also AVA's [`extensions` option](../06-configuration.md#options).
|
||||
|
||||
## Make AVA skip your project's Babel options
|
||||
|
||||
You may not want AVA to use your project's Babel options, for example if your project is relying on Babel 6. Set the `babelrc` and `configFile` options to `false`.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"testOptions": {
|
||||
"babelrc": false,
|
||||
"configFile": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Disable AVA's stage-4 preset
|
||||
|
||||
You can disable AVA's stage-4 preset.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"testOptions": {
|
||||
"presets": [
|
||||
["module:ava/stage-4", false]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that this *does not* stop AVA from compiling your test files using Babel.
|
||||
|
||||
If you want, you can disable the preset in your project's Babel configuration.
|
||||
|
||||
## Preserve ES module syntax
|
||||
|
||||
By default AVA's stage-4 preset will convert ES module syntax to CommonJS. This can be disabled.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"testOptions": {
|
||||
"presets": [
|
||||
["module:ava/stage-4", {"modules": false}]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You'll have to use the [`esm`](https://github.com/standard-things/esm) module so that AVA can still load your test files. [See our recipe for details](./es-modules.md).
|
||||
|
||||
## Disable AVA's Babel pipeline
|
||||
|
||||
You can completely disable AVA's use of Babel.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": false,
|
||||
"compileEnhancements": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Experimental feature: No Babel out of the box
|
||||
|
||||
A future release of AVA will not use Babel out of the box. You can opt in to this feature. **This feature may change or be removed at any time**:
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```js
|
||||
{
|
||||
"ava": {
|
||||
"nonSemVerExperiments": {
|
||||
"noBabelOutOfTheBox": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This disables AVA's Babel pipeline, though you can still enable it by configuring it as described above.
|
||||
|
||||
`compileEnhancements` can no longer be configured on the top-level AVA configuration. It must be configured in AVA's `babel` configuration instead. It defaults to `true`.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"nonSemVerExperiments": {
|
||||
"noBabelOutOfTheBox": true
|
||||
},
|
||||
"babel": {
|
||||
"compileEnhancements": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can disable the non-enhancement compilation of your test files by setting `testOptions` to `false`.
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"nonSemVerExperiments": {
|
||||
"noBabelOutOfTheBox": true
|
||||
},
|
||||
"babel": {
|
||||
"testOptions": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Use Babel polyfills
|
||||
|
||||
AVA lets you write your tests using new JavaScript syntax, even on Node.js versions that otherwise wouldn't support it. However, it doesn't add or modify built-ins of your current environment. Using AVA would, for example, not provide modern features such as `Object.entries()` to an underlying Node.js 6 environment.
|
||||
|
||||
By loading [Babel's `polyfill` module](https://babeljs.io/docs/usage/polyfill/) you can opt in to these features. Note that this will modify the environment, which may influence how your program behaves.
|
||||
|
||||
You can enable the `polyfill` module by adding it to AVA's `require` option.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"require": [
|
||||
"@babel/polyfill"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You'll need to install `@babel/polyfill` yourself.
|
||||
|
||||
## Compile sources
|
||||
|
||||
AVA does not currently compile source files. You'll have to load [Babel's `register` module](http://babeljs.io/docs/usage/require/), which will compile source files as needed.
|
||||
|
||||
You can enable the `register` module by adding it to AVA's `require` option.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"require": [
|
||||
"@babel/register"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You'll need to install `@babel/register` yourself.
|
||||
|
||||
`@babel/register` will *also* process your test and helper files. For most use cases this is unnecessary. If you create a new file that requires `@babel/register` you can tell it which file paths to ignore. For instance in your `test` directory create `_register.js`:
|
||||
|
||||
```js
|
||||
// test/_register.js:
|
||||
require('@babel/register')({
|
||||
// These patterns are relative to the project directory (where the `package.json` file lives):
|
||||
ignore: ['node_modules/*', 'test/*']
|
||||
});
|
||||
```
|
||||
|
||||
Now instead of requiring `@babel/register`, require `./test/_register` instead.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"require": [
|
||||
"./test/_register.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that loading `@babel/register` in every worker process has a non-trivial performance cost. If you have lots of test files, you may want to consider using a build step to compile your sources *before* running your tests. This isn't ideal, since it complicates using AVA's watch mode, so we recommend using `@babel/register` until the performance penalty becomes too great. Setting up a precompilation step is out of scope for this document, but we recommend you check out one of the many [build systems that support Babel](http://babeljs.io/docs/setup/). There is an [issue](https://github.com/avajs/ava/issues/577) discussing ways we could make this experience better.
|
||||
|
||||
## Webpack aliases
|
||||
|
||||
[Webpack aliases](https://webpack.js.org/configuration/resolve/#resolve-alias) can be used to provide a shortcut to deeply nested or otherwise inconvenient paths. If you already use aliases in your source files, you'll need to make sure you can use the same aliases in your test files.
|
||||
|
||||
Install `babel-plugin-webpack-alias-7` as a dev-dependency. Then add the plugin to AVA's Babel config:
|
||||
|
||||
`package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"testOptions": {
|
||||
"plugins": [
|
||||
[
|
||||
"babel-plugin-webpack-alias-7",
|
||||
{
|
||||
"config": "./path/to/webpack.config.test.js"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[Babel options]: https://babeljs.io/docs/en/options
|
||||
Find out more in [`@ava/babel`](https://github.com/avajs/babel).
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
# Configuring Babel
|
||||
|
||||
Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/docs/recipes/babelrc.md)
|
||||
|
||||
This recipe has moved. Please see our [new Babel recipe](babel.md).
|
||||
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
Translations: [Español](https://github.com/avajs/ava-docs/blob/master/es_ES/docs/recipes/code-coverage.md), [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/docs/recipes/code-coverage.md), [Italiano](https://github.com/avajs/ava-docs/blob/master/it_IT/docs/recipes/code-coverage.md), [日本語](https://github.com/avajs/ava-docs/blob/master/ja_JP/docs/recipes/code-coverage.md), [Português](https://github.com/avajs/ava-docs/blob/master/pt_BR/docs/recipes/code-coverage.md), [Русский](https://github.com/avajs/ava-docs/blob/master/ru_RU/docs/recipes/code-coverage.md), [简体中文](https://github.com/avajs/ava-docs/blob/master/zh_CN/docs/recipes/code-coverage.md)
|
||||
|
||||
Use the [nyc] command-line-client for [Istanbul] to compute the code coverage of your tests.
|
||||
Use [`nyc`] to compute the code coverage of your tests.
|
||||
|
||||
First install [nyc]:
|
||||
First install [`nyc`]:
|
||||
|
||||
```
|
||||
$ npm install --save-dev nyc
|
||||
```
|
||||
|
||||
At its simplest run AVA through [nyc]. In your `package.json` file:
|
||||
At its simplest run AVA through [`nyc`]. In your `package.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -27,7 +27,4 @@ You may want to exclude the `.nyc_output` and `coverage` directories from source
|
|||
coverage
|
||||
```
|
||||
|
||||
If you're compiling your source files using Babel you may want to apply Istanbul's instrumentation as part of the source file compilation. This will yield better results than instrumenting Babel's output. See Istanbul's [*Using Istanbul With ES2015+* tutorial](https://istanbul.js.org/docs/tutorials/es2015/). AVA sets `NODE_ENV=test` for you. Note that as of February 2018 this tutorial hasn't yet been updated for Babel 7.
|
||||
|
||||
[Istanbul]: https://istanbul.js.org/
|
||||
[nyc]: https://github.com/istanbuljs/nyc
|
||||
[`nyc`]: https://github.com/istanbuljs/nyc
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ Configure it in your `package.json` or `ava.config.js` file, and add it to AVA's
|
|||
}
|
||||
```
|
||||
|
||||
By default AVA converts ES module syntax to CommonJS. [You can disable this](./babel.md#preserve-es-module-syntax).
|
||||
|
||||
You can now use native ES modules with AVA:
|
||||
|
||||
```js
|
||||
|
|
@ -47,29 +45,13 @@ test('2 + 2 = 4', t => {
|
|||
});
|
||||
```
|
||||
|
||||
You need to configure AVA to recognize `.mjs` extensions. If you want AVA to apply its Babel presets use the following.
|
||||
You need to configure AVA to recognize `.mjs` extensions;
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"extensions": [
|
||||
"js",
|
||||
"mjs"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively you can use:
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"babel": false,
|
||||
"extensions": [
|
||||
"js",
|
||||
"mjs"
|
||||
|
|
@ -77,15 +59,3 @@ Alternatively you can use:
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or leave Babel enabled (which means it's applied to `.js` files), but don't apply it to `.mjs` files:
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"extensions": [
|
||||
"mjs"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Until [1.4.1](https://github.com/avajs/ava/releases/tag/v1.4.1) AVA came bundled
|
|||
|
||||
This guide assumes you've already set up Flow for your project. Note that AVA's definition as been tested with version 0.95.1.
|
||||
|
||||
We recommend you use AVA's built-in Babel pipeline to strip Flow type annotations and declarations. AVA automatically applies your project's Babel configuration, so everything may just work without changes. Alternatively install [`@babel/plugin-transform-flow-strip-types`](https://www.npmjs.com/package/@babel/plugin-transform-flow-strip-types) and customize AVA's configuration in the `package.json` file (or the `ava.config.js` file) as follows.
|
||||
We recommend you use AVA's [Babel support](https://github.com/avajs/babel) to strip Flow type annotations and declarations. AVA automatically applies your project's Babel configuration, so everything may just work without changes. Alternatively install [`@babel/plugin-transform-flow-strip-types`](https://www.npmjs.com/package/@babel/plugin-transform-flow-strip-types) and customize AVA's configuration in the `package.json` file (or the `ava.config.js` file) as follows.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ We recommend you use AVA's built-in Babel pipeline to strip Flow type annotation
|
|||
}
|
||||
```
|
||||
|
||||
See our [Babel documentation](babel.md) for more details.
|
||||
See our [`@ava/babel`](https://github.com/avajs/babel) for more details.
|
||||
|
||||
## Writing tests
|
||||
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
# JSPM and SystemJS for ES2015
|
||||
|
||||
Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/docs/recipes/jspm-systemjs.md)
|
||||
|
||||
It requires a special loader helper to correctly resolve `import`s of JSPM packages when using AVA. The purpose of the loader is to allow you to run your tests without having to pre-build your JSPM project.
|
||||
|
||||
## Setup
|
||||
|
||||
This recipe has only been tested with JSPM v0.17.0-beta.22, but it should work with any version of JSPM v0.17 and may work with v0.16.
|
||||
|
||||
### Babel
|
||||
|
||||
Set up your Babel options to work with AVA if you have not already. NOTE: You can keep additional configuration in your JSPM config files to override these settings during bundling and building.
|
||||
|
||||
```
|
||||
$ npm install --save-dev @babel/preset-env
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"presets": ["@babel/preset-env"]
|
||||
}
|
||||
```
|
||||
|
||||
You can find more information about setting up Babel with AVA in the [Babel recipe](babel.md).
|
||||
|
||||
### JSPM Loader Helper
|
||||
|
||||
You will need to install the [AVA JSPM loader](https://github.com/skorlir/ava-jspm-loader) as a dev dependency. You will also need to install [`@babel/register`](https://www.npmjs.com/package/@babel/register).
|
||||
|
||||
```
|
||||
$ npm install --save-dev ava-jspm-loader @babel/register
|
||||
```
|
||||
You will also need to update your AVA config in the `package.json` or `ava.config.js` to use the JSPM loader.
|
||||
|
||||
**`package.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ava": {
|
||||
"require": [
|
||||
"@babel/register",
|
||||
"ava-jspm-loader"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
NOTE: If you use async/await in your source code (not in your test code), you will need to install [`@babel/polyfill`](https://www.npmjs.com/package/@babel/polyfill) and add it to your `require` array.
|
||||
|
||||
### Example test file
|
||||
|
||||
Note that you will need to use `System.import` paths for all of your project files. So, if you named your project `app` and you want to import your `main.js` into a test file, you will need to `import main from 'app/main'`.
|
||||
|
||||
```js
|
||||
import test from 'ava';
|
||||
import main from 'app/main'; // Maps to your JSPM config for "app/main.js"
|
||||
import BigNumber from 'bignumber.js'; // In jspm_packages
|
||||
|
||||
function fn() {
|
||||
return Promise.resolve(new BigNumber('1234567890.123456789'));
|
||||
}
|
||||
|
||||
test('example test', async t => {
|
||||
t.is((await fn()).toString(), '1234567890.123456789');
|
||||
});
|
||||
```
|
||||
|
|
@ -4,7 +4,7 @@ Translations: [Español](https://github.com/avajs/ava-docs/blob/master/es_ES/doc
|
|||
|
||||
## Setting up Babel
|
||||
|
||||
AVA automatically extends your regular (project-level) Babel configuration. You should be able to use React in your test files without any additional configuration.
|
||||
When you [enable Babel](https://github.com/avajs/babel), AVA will automatically extend your regular (project-level) Babel configuration. You should be able to use React in your test files without any additional configuration.
|
||||
|
||||
However if you want to set it up explicitly, add the preset to the test options in AVA's Babel pipeline by modifying your `package.json` or `ava.config.js` file.
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ However if you want to set it up explicitly, add the preset to the test options
|
|||
}
|
||||
```
|
||||
|
||||
You can find more information about setting up Babel with AVA in the [Babel recipe](babel.md).
|
||||
You can find more information in [`@ava/babel`](https://github.com/avajs/babel).
|
||||
|
||||
## Using [Enzyme](https://github.com/airbnb/enzyme)
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ hooks(['vue', 'js']).exclude(({filename}) => filename.match(/\/node_modules\//))
|
|||
|
||||
**Note:** If you are using _babel-plugin-webpack-alias-7_, you must also exclude your webpack file - e.g. `filename.includes(/\/node_modules\//) || filename.includes('webpack.config.test.js')`
|
||||
|
||||
You can find more information about setting up Babel with AVA in the [Babel recipe](babel.md).
|
||||
You can find more information about setting up Babel with AVA in [`@ava/babel`](https://github.com/avajs/babel).
|
||||
|
||||
## Sample snapshot test
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,10 @@ function load(projectDir, overrides) {
|
|||
({conf, babelProvider} = configCache.get(projectDir));
|
||||
} else {
|
||||
conf = loadConfig({resolveFrom: projectDir});
|
||||
const {nonSemVerExperiments: experiments} = conf;
|
||||
|
||||
if (!experiments.noBabelOutOfTheBox || conf.babel !== undefined) {
|
||||
babelProvider = babelManager({experiments, projectDir});
|
||||
babelProvider.validateConfig(conf.babel, conf.compileEnhancements !== false);
|
||||
if (Reflect.has(conf, 'babel')) {
|
||||
babelProvider = babelManager({projectDir});
|
||||
babelProvider.validateConfig(conf.babel);
|
||||
}
|
||||
|
||||
configCache.set(projectDir, {conf, babelProvider});
|
||||
|
|
@ -38,7 +37,7 @@ function load(projectDir, overrides) {
|
|||
}
|
||||
}
|
||||
|
||||
const extensions = normalizeExtensions(conf.extensions, babelProvider, {experiments: conf.nonSemVerExperiments});
|
||||
const extensions = normalizeExtensions(conf.extensions, babelProvider);
|
||||
const globs = {cwd: projectDir, ...normalizeGlobs(conf.files, conf.helpers, conf.sources, extensions.all)};
|
||||
|
||||
const helper = Object.freeze({
|
||||
|
|
|
|||
53
lib/api.js
53
lib/api.js
|
|
@ -57,7 +57,7 @@ class Api extends Emittery {
|
|||
}
|
||||
}
|
||||
|
||||
async run(files = [], runtimeOptions = {}) { // eslint-disable-line complexity
|
||||
async run(files = [], runtimeOptions = {}) {
|
||||
let setupOrGlobError;
|
||||
files = files.map(file => path.resolve(this.options.resolveTestsFrom, file));
|
||||
|
||||
|
|
@ -118,11 +118,7 @@ class Api extends Emittery {
|
|||
let helpers;
|
||||
|
||||
const {babelProvider} = this.options;
|
||||
const enabledBabelProvider = babelProvider !== undefined && (
|
||||
babelProvider.isEnabled() || (babelProvider.legacy && babelProvider.compileEnhancements !== null)
|
||||
) ?
|
||||
babelProvider :
|
||||
null;
|
||||
const enabledBabelProvider = babelProvider !== undefined && babelProvider.isEnabled() ? babelProvider : null;
|
||||
|
||||
try {
|
||||
cacheDir = this._createCacheDir();
|
||||
|
|
@ -210,44 +206,13 @@ class Api extends Emittery {
|
|||
const testFiles = files.map(file => fs.realpathSync(file));
|
||||
const helperFiles = helpers.map(file => fs.realpathSync(file));
|
||||
|
||||
if (enabledBabelProvider.legacy) {
|
||||
const full = {testFiles: [], helperFiles: []};
|
||||
const enhancements = {testFiles: [], helperFiles: []};
|
||||
for (const realpath of testFiles) {
|
||||
if (this._regexpBabelExtensions.test(path.basename(realpath))) { // eslint-disable-line max-depth
|
||||
full.testFiles.push(realpath);
|
||||
} else {
|
||||
enhancements.testFiles.push(realpath);
|
||||
}
|
||||
}
|
||||
|
||||
for (const realpath of helperFiles) {
|
||||
if (this._regexpBabelExtensions.test(path.basename(realpath))) { // eslint-disable-line max-depth
|
||||
full.helperFiles.push(realpath);
|
||||
} else {
|
||||
enhancements.helperFiles.push(realpath);
|
||||
}
|
||||
}
|
||||
|
||||
babelState = {
|
||||
...enabledBabelProvider.isEnabled() && enabledBabelProvider.compile({
|
||||
cacheDir,
|
||||
...full
|
||||
}),
|
||||
...enabledBabelProvider.compileEnhancements !== null && enabledBabelProvider.compileEnhancements({
|
||||
cacheDir,
|
||||
...enhancements
|
||||
})
|
||||
};
|
||||
} else {
|
||||
babelState = {
|
||||
...enabledBabelProvider.compile({
|
||||
cacheDir,
|
||||
testFiles: testFiles.filter(realpath => this._regexpBabelExtensions.test(path.basename(realpath))),
|
||||
helperFiles: helperFiles.filter(realpath => this._regexpBabelExtensions.test(path.basename(realpath)))
|
||||
})
|
||||
};
|
||||
}
|
||||
babelState = {
|
||||
...enabledBabelProvider.compile({
|
||||
cacheDir,
|
||||
testFiles: testFiles.filter(realpath => this._regexpBabelExtensions.test(path.basename(realpath))),
|
||||
helperFiles: helperFiles.filter(realpath => this._regexpBabelExtensions.test(path.basename(realpath)))
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
// Resolve the correct concurrency value.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
'use strict';
|
||||
const concordance = require('concordance');
|
||||
const empower = require('empower-core');
|
||||
const isError = require('is-error');
|
||||
const isPromise = require('is-promise');
|
||||
const concordanceOptions = require('./concordance-options').default;
|
||||
const concordanceDiffOptions = require('./concordance-options').diff;
|
||||
const enhanceAssert = require('./enhance-assert');
|
||||
const snapshotManager = require('./snapshot-manager');
|
||||
|
||||
function formatDescriptorDiff(actualDescriptor, expectedDescriptor, options) {
|
||||
|
|
@ -27,6 +25,10 @@ function formatWithLabel(label, value) {
|
|||
return formatDescriptorWithLabel(label, concordance.describe(value, concordanceOptions));
|
||||
}
|
||||
|
||||
function formatPowerAssertValue(value) {
|
||||
return concordance.format(value, concordanceOptions);
|
||||
}
|
||||
|
||||
const hasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
const noop = () => {};
|
||||
const notImplemented = () => {
|
||||
|
|
@ -236,20 +238,20 @@ class Assertions {
|
|||
pending = notImplemented,
|
||||
fail = notImplemented,
|
||||
skip = notImplemented,
|
||||
compareWithSnapshot = notImplemented
|
||||
compareWithSnapshot = notImplemented,
|
||||
powerAssert
|
||||
} = {}) {
|
||||
const withSkip = assertionFn => {
|
||||
assertionFn.skip = skip;
|
||||
return assertionFn;
|
||||
};
|
||||
|
||||
// When adding new enhanced functions with new patterns, don't forget to add to
|
||||
// https://github.com/avajs/babel-preset-transform-test-files/blob/master/espower-patterns.json
|
||||
// Then release a new version of that preset and bump the SemVer range here.
|
||||
const withPowerAssert = (pattern, assertionFn) => empower(assertionFn, {
|
||||
// When adding new enhanced functions with new patterns, don't forget to
|
||||
// enable the pattern in the power-assert compilation step in @ava/babel.
|
||||
const withPowerAssert = (pattern, assertionFn) => powerAssert.empower(assertionFn, {
|
||||
onError: event => {
|
||||
if (event.powerAssertContext) {
|
||||
event.error.statements = enhanceAssert.formatter(event.powerAssertContext);
|
||||
event.error.statements = powerAssert.format(event.powerAssertContext, formatPowerAssertValue);
|
||||
}
|
||||
|
||||
fail(event.error);
|
||||
|
|
@ -835,21 +837,38 @@ class Assertions {
|
|||
pass();
|
||||
});
|
||||
|
||||
this.assert = withSkip(withPowerAssert(
|
||||
'assert(value, [message])',
|
||||
(actual, message) => {
|
||||
checkMessage('assert', message, true);
|
||||
if (powerAssert === undefined) {
|
||||
this.assert = withSkip((actual, message) => {
|
||||
if (!checkMessage('assert', message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!actual) {
|
||||
throw new AssertionError({
|
||||
fail(new AssertionError({
|
||||
assertion: 'assert',
|
||||
message,
|
||||
operator: '!!',
|
||||
values: [formatWithLabel('Value is not truthy:', actual)]
|
||||
});
|
||||
}));
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.assert = withSkip(withPowerAssert(
|
||||
'assert(value, [message])',
|
||||
(actual, message) => {
|
||||
checkMessage('assert', message, true);
|
||||
|
||||
if (!actual) {
|
||||
throw new AssertionError({
|
||||
assertion: 'assert',
|
||||
message,
|
||||
operator: '!!',
|
||||
values: [formatWithLabel('Value is not truthy:', actual)]
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Assertions = Assertions;
|
||||
|
|
|
|||
|
|
@ -1,63 +1,25 @@
|
|||
const pkg = require('../package.json');
|
||||
|
||||
module.exports = ({experiments, projectDir}) => {
|
||||
module.exports = ({projectDir}) => {
|
||||
const ava = {version: pkg.version};
|
||||
const makeProvider = require('@ava/babel');
|
||||
|
||||
if (experiments.noBabelOutOfTheBox) {
|
||||
let fatal;
|
||||
const provider = makeProvider({
|
||||
negotiateProtocol(identifiers) {
|
||||
if (!identifiers.includes('noBabelOutOfTheBox')) {
|
||||
fatal = new Error('TODO: Throw error when @ava/babel does not negotiate the expected protocol');
|
||||
return null;
|
||||
}
|
||||
|
||||
return {identifier: 'noBabelOutOfTheBox', ava, projectDir};
|
||||
}
|
||||
});
|
||||
|
||||
if (fatal) {
|
||||
throw fatal;
|
||||
}
|
||||
|
||||
return {
|
||||
legacy: false,
|
||||
...provider,
|
||||
// Don't pass the legacy compileEnhancements value.
|
||||
validateConfig: babelConfig => provider.validateConfig(babelConfig)
|
||||
};
|
||||
}
|
||||
|
||||
let fatal;
|
||||
const negotiateProtocol = identifiers => {
|
||||
if (!identifiers.includes('legacy')) {
|
||||
fatal = new Error('TODO: Throw error when @ava/babel does not negotiate the expected protocol');
|
||||
return null;
|
||||
const provider = makeProvider({
|
||||
negotiateProtocol(identifiers) {
|
||||
// TODO: Settle on a identifier before releasing AVA@3; fix error message.
|
||||
if (!identifiers.includes('noBabelOutOfTheBox')) {
|
||||
fatal = new Error('TODO: Throw error when @ava/babel does not negotiate the expected protocol');
|
||||
return null;
|
||||
}
|
||||
|
||||
return {identifier: 'noBabelOutOfTheBox', ava, projectDir};
|
||||
}
|
||||
|
||||
return {identifier: 'legacy', ava, projectDir};
|
||||
};
|
||||
|
||||
const [full, enhancementsOnly] = [makeProvider({negotiateProtocol}), makeProvider({negotiateProtocol})];
|
||||
});
|
||||
|
||||
if (fatal) {
|
||||
throw fatal;
|
||||
}
|
||||
|
||||
return {
|
||||
legacy: true,
|
||||
...full,
|
||||
validateConfig(babelConfig, compileEnhancements) {
|
||||
full.validateConfig({babelConfig, compileEnhancements, enhancementsOnly: false});
|
||||
enhancementsOnly.validateConfig({compileEnhancements, enhancementsOnly: true});
|
||||
},
|
||||
get compileEnhancements() {
|
||||
if (enhancementsOnly.isEnabled()) {
|
||||
return enhancementsOnly.compile;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return provider;
|
||||
};
|
||||
|
|
|
|||
11
lib/cli.js
11
lib/cli.js
|
|
@ -232,7 +232,7 @@ exports.run = async () => { // eslint-disable-line complexity
|
|||
console.log(chalk.magenta(` ${figures.warning} Experiments are enabled. These are unsupported and may change or be removed at any time.`));
|
||||
}
|
||||
|
||||
if (experiments.noBabelOutOfTheBox && typeof conf.compileEnhancements === 'boolean') {
|
||||
if (typeof conf.compileEnhancements === 'boolean') {
|
||||
exit('Enhancement compilation must be configured in AVA’s Babel options');
|
||||
}
|
||||
|
||||
|
|
@ -248,10 +248,10 @@ exports.run = async () => { // eslint-disable-line complexity
|
|||
const validateEnvironmentVariables = require('./environment-variables');
|
||||
|
||||
let babelProvider;
|
||||
if (!experiments.noBabelOutOfTheBox || conf.babel !== undefined) {
|
||||
if (Reflect.has(conf, 'babel')) {
|
||||
try {
|
||||
babelProvider = babelManager({experiments, projectDir});
|
||||
babelProvider.validateConfig(conf.babel, conf.compileEnhancements !== false);
|
||||
babelProvider = babelManager({projectDir});
|
||||
babelProvider.validateConfig(conf.babel);
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
|
|
@ -266,7 +266,7 @@ exports.run = async () => { // eslint-disable-line complexity
|
|||
|
||||
let extensions;
|
||||
try {
|
||||
extensions = normalizeExtensions(conf.extensions, babelProvider, {experiments});
|
||||
extensions = normalizeExtensions(conf.extensions, babelProvider);
|
||||
} catch (error) {
|
||||
exit(error.message);
|
||||
}
|
||||
|
|
@ -313,7 +313,6 @@ exports.run = async () => { // eslint-disable-line complexity
|
|||
babelProvider,
|
||||
cacheEnabled: combined.cache !== false,
|
||||
color: combined.color,
|
||||
compileEnhancements: combined.compileEnhancements !== false,
|
||||
concurrency: combined.concurrency || 0,
|
||||
debug,
|
||||
experiments,
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
'use strict';
|
||||
const concordance = require('concordance');
|
||||
const dotProp = require('dot-prop');
|
||||
const generate = require('@babel/generator').default;
|
||||
const concordanceOptions = require('./concordance-options').default;
|
||||
|
||||
const computeStatement = node => generate(node).code;
|
||||
const getNode = (ast, path) => dotProp.get(ast, path.replace(/\//g, '.'));
|
||||
|
||||
const formatter = context => {
|
||||
const ast = JSON.parse(context.source.ast);
|
||||
const args = context.args[0].events;
|
||||
return args
|
||||
.map(arg => {
|
||||
const node = getNode(ast, arg.espath);
|
||||
const statement = computeStatement(node);
|
||||
const formatted = concordance.format(arg.value, concordanceOptions);
|
||||
return [statement, formatted];
|
||||
})
|
||||
.reverse();
|
||||
};
|
||||
|
||||
module.exports.formatter = formatter;
|
||||
|
|
@ -1,47 +1,10 @@
|
|||
const legacy = (enhancementsOnly, babelIsEnabled, babelOnly) => {
|
||||
module.exports = (configuredExtensions = [], babelProvider = null) => {
|
||||
const babelExtensions = babelProvider !== null && babelProvider.isEnabled() ? babelProvider.getExtensions() : [];
|
||||
|
||||
// Combine all extensions possible for testing. Remove duplicate extensions.
|
||||
const duplicates = [];
|
||||
const seen = new Set();
|
||||
for (const ext of [...enhancementsOnly, ...babelOnly]) {
|
||||
if (seen.has(ext)) {
|
||||
duplicates.push(ext);
|
||||
} else {
|
||||
seen.add(ext);
|
||||
}
|
||||
}
|
||||
|
||||
// Decide if and where to add the default `js` extension. Keep in mind it's not
|
||||
// added if extensions have been explicitly given.
|
||||
if (!seen.has('js')) {
|
||||
if (babelIsEnabled && babelOnly.length === 0) {
|
||||
seen.add('js');
|
||||
babelOnly.push('js');
|
||||
}
|
||||
|
||||
if (!babelIsEnabled && enhancementsOnly.length === 0) {
|
||||
seen.add('js');
|
||||
enhancementsOnly.push('js');
|
||||
}
|
||||
} else if (babelIsEnabled && babelOnly.length === 0) {
|
||||
// If Babel is not disabled, and has the default extensions (or, explicitly,
|
||||
// no configured extensions), then the `js` extension must have come from
|
||||
// the `enhancementsOnly` value. That's not allowed since it'd be a
|
||||
// roundabout way of disabling Babel.
|
||||
throw new Error('Cannot specify generic \'js\' extension without disabling AVA\'s Babel usage.');
|
||||
}
|
||||
|
||||
if (duplicates.length > 0) {
|
||||
throw new Error(`Unexpected duplicate extensions in options: '${duplicates.join('\', \'')}'.`);
|
||||
}
|
||||
|
||||
return {all: [...seen], enhancementsOnly, babelOnly};
|
||||
};
|
||||
|
||||
const noBabelOutOfTheBox = (extensions = [], babelOnly = []) => {
|
||||
// Combine all extensions possible for testing. Remove duplicate extensions.
|
||||
const duplicates = [];
|
||||
const seen = new Set();
|
||||
for (const ext of [...extensions, ...babelOnly]) {
|
||||
for (const ext of [...configuredExtensions, ...babelExtensions]) {
|
||||
if (seen.has(ext)) {
|
||||
duplicates.push(ext);
|
||||
} else {
|
||||
|
|
@ -54,21 +17,10 @@ const noBabelOutOfTheBox = (extensions = [], babelOnly = []) => {
|
|||
}
|
||||
|
||||
// Assume `babelOnly` would contain the `js` extension, so if it was not seen
|
||||
// and `extensions` has not been explicitly given, default it to `js`.
|
||||
if (!seen.has('js') && extensions === undefined) {
|
||||
// and `extensions` is empty, default it to `js`.
|
||||
if (!seen.has('js') && configuredExtensions.length === 0) {
|
||||
seen.add('js');
|
||||
}
|
||||
|
||||
return {all: [...seen], babelOnly};
|
||||
};
|
||||
|
||||
module.exports = (configuredExtensions, babelProvider, {experiments = {}} = {}) => {
|
||||
const babelIsEnabled = babelProvider !== undefined && babelProvider.isEnabled();
|
||||
const babelExtensions = babelIsEnabled ? babelProvider.getExtensions() : [];
|
||||
|
||||
if (experiments.noBabelOutOfTheBox) {
|
||||
return noBabelOutOfTheBox(configuredExtensions, babelExtensions);
|
||||
}
|
||||
|
||||
return legacy(configuredExtensions || [], babelIsEnabled, babelExtensions);
|
||||
return {all: [...seen], babelOnly: babelExtensions};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const pkgConf = require('pkg-conf');
|
|||
|
||||
const NO_SUCH_FILE = Symbol('no ava.config.js file');
|
||||
const MISSING_DEFAULT_EXPORT = Symbol('missing default export');
|
||||
const EXPERIMENTS = new Set(['noBabelOutOfTheBox', 'tryAssertion']);
|
||||
const EXPERIMENTS = new Set(['tryAssertion']);
|
||||
|
||||
function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) { // eslint-disable-line complexity
|
||||
let packageConf = pkgConf.sync('ava', {cwd: resolveFrom});
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class Runner extends Emittery {
|
|||
this.failWithoutAssertions = options.failWithoutAssertions !== false;
|
||||
this.file = options.file;
|
||||
this.match = options.match || [];
|
||||
this.powerAssert = undefined; // Assigned later.
|
||||
this.projectDir = options.projectDir;
|
||||
this.recordNewSnapshots = options.recordNewSnapshots === true;
|
||||
this.runOnlyExclusive = options.runOnlyExclusive === true;
|
||||
|
|
@ -276,6 +277,7 @@ class Runner extends Emittery {
|
|||
compareTestSnapshot: this.boundCompareTestSnapshot,
|
||||
updateSnapshots: this.updateSnapshots,
|
||||
metadata: task.metadata,
|
||||
powerAssert: this.powerAssert,
|
||||
title: `${task.title}${titleSuffix || ''}`
|
||||
}));
|
||||
const outcome = await this.runMultiple(hooks, this.serial);
|
||||
|
|
@ -317,6 +319,7 @@ class Runner extends Emittery {
|
|||
compareTestSnapshot: this.boundCompareTestSnapshot,
|
||||
updateSnapshots: this.updateSnapshots,
|
||||
metadata: task.metadata,
|
||||
powerAssert: this.powerAssert,
|
||||
title: task.title,
|
||||
registerUniqueTitle: this.registerUniqueTitle
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ class ExecutionContext extends assert.Assertions {
|
|||
},
|
||||
compareWithSnapshot: options => {
|
||||
return test.compareWithSnapshot(options);
|
||||
}
|
||||
},
|
||||
powerAssert: test.powerAssert
|
||||
});
|
||||
testMap.set(this, test);
|
||||
|
||||
|
|
@ -193,6 +194,7 @@ class Test {
|
|||
this.failWithoutAssertions = options.failWithoutAssertions;
|
||||
this.fn = options.fn;
|
||||
this.metadata = options.metadata;
|
||||
this.powerAssert = options.powerAssert;
|
||||
this.title = options.title;
|
||||
this.registerUniqueTitle = options.registerUniqueTitle;
|
||||
this.logs = [];
|
||||
|
|
|
|||
|
|
@ -104,11 +104,19 @@ ipc.options.then(options => {
|
|||
// Store value in case to prevent required modules from modifying it.
|
||||
const testPath = options.file;
|
||||
|
||||
// Install basic source map support.
|
||||
const sourceMapSupport = require('source-map-support');
|
||||
sourceMapSupport.install({
|
||||
environment: 'node',
|
||||
handleUncaughtExceptions: false
|
||||
});
|
||||
|
||||
// Install before processing options.require, so if helpers are added to the
|
||||
// require configuration the *compiled* helper will be loaded.
|
||||
if (options.babelState !== null) {
|
||||
const {experiments, projectDir} = options;
|
||||
const babelProvider = babelManager({experiments, projectDir});
|
||||
const {projectDir} = options;
|
||||
const babelProvider = babelManager({projectDir});
|
||||
runner.powerAssert = babelProvider.powerAssert;
|
||||
babelProvider.installHook(options.babelState);
|
||||
}
|
||||
|
||||
|
|
|
|||
752
package-lock.json
generated
752
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -57,8 +57,6 @@
|
|||
"typescript"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ava/babel": "^0.1.0",
|
||||
"@babel/generator": "^7.7.7",
|
||||
"@concordance/react": "^2.0.0",
|
||||
"ansi-escapes": "^4.3.0",
|
||||
"ansi-styles": "^4.2.0",
|
||||
|
|
@ -80,9 +78,7 @@
|
|||
"currently-unhandled": "^0.4.1",
|
||||
"debug": "^4.1.1",
|
||||
"del": "^5.1.0",
|
||||
"dot-prop": "^5.2.0",
|
||||
"emittery": "^0.5.1",
|
||||
"empower-core": "^1.2.0",
|
||||
"equal-length": "^1.0.0",
|
||||
"escape-string-regexp": "^2.0.0",
|
||||
"esm": "^3.2.25",
|
||||
|
|
@ -111,6 +107,7 @@
|
|||
"pretty-ms": "^5.1.0",
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"slash": "^3.0.0",
|
||||
"source-map-support": "^0.5.16",
|
||||
"stack-utils": "^2.0.1",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"supertap": "^1.0.0",
|
||||
|
|
@ -123,6 +120,7 @@
|
|||
"yargs": "^15.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ava/babel": "^0.2.0",
|
||||
"@babel/core": "^7.7.7",
|
||||
"@types/node": "^10.17.11",
|
||||
"cli-table3": "^0.5.1",
|
||||
|
|
@ -139,7 +137,6 @@
|
|||
"signal-exit": "^3.0.0",
|
||||
"sinon": "^7.5.0",
|
||||
"source-map-fixtures": "^2.1.0",
|
||||
"source-map-support": "^0.5.16",
|
||||
"tap": "^14.10.5",
|
||||
"temp-write": "^4.0.0",
|
||||
"touch": "^3.1.0",
|
||||
|
|
|
|||
16
readme.md
16
readme.md
|
|
@ -25,7 +25,7 @@ Translations: [Español](https://github.com/avajs/ava-docs/blob/master/es_ES/rea
|
|||
- Includes TypeScript definitions
|
||||
- [Magic assert](#magic-assert)
|
||||
- [Isolated environment for each test file](./docs/01-writing-tests.md#process-isolation)
|
||||
- [Write your tests using the latest JavaScript syntax](#latest-javascript-support)
|
||||
- [Write your tests using the latest JavaScript syntax](https://github.com/avajs/babel)
|
||||
- [Promise support](./docs/01-writing-tests.md#promise-support)
|
||||
- [Async function support](./docs/01-writing-tests.md#async-function-support)
|
||||
- [Observable support](./docs/01-writing-tests.md#observable-support)
|
||||
|
|
@ -121,16 +121,6 @@ AVA adds code excerpts and clean diffs for actual and expected values. If values
|
|||
|
||||
AVA automatically removes unrelated lines in stack traces, allowing you to find the source of an error much faster, as seen above.
|
||||
|
||||
### Latest JavaScript support
|
||||
|
||||
AVA uses [Babel 7](https://babeljs.io) so you can use the latest JavaScript syntax in your tests. There is no extra setup required. You don't need to be using Babel in your own project for this to work either.
|
||||
|
||||
We aim to support all [finished syntax proposals](https://github.com/tc39/proposals/blob/master/finished-proposals.md), as well as all syntax from ratified JavaScript versions (e.g. ES2017). See our [`@ava/stage-4`](https://github.com/avajs/babel-preset-stage-4) preset for the currently supported proposals.
|
||||
|
||||
Please note that we do not add or modify built-ins. For example, if you use [`Object.fromEntries()`](https://github.com/tc39/proposal-object-from-entries) in your tests, they will crash in Node.js 10 which does not implement this method.
|
||||
|
||||
You can disable this syntax support, or otherwise customize AVA's Babel pipeline. See our [Babel recipe] for more details.
|
||||
|
||||
### Parallel runs in CI
|
||||
|
||||
AVA automatically detects whether your CI environment supports parallel builds. Each build will run a subset of all test files, while still making sure all tests get executed. See the [`ci-parallel-vars`](https://www.npmjs.com/package/ci-parallel-vars) package for a list of supported CI environments.
|
||||
|
|
@ -161,7 +151,7 @@ We have a growing list of [common pitfalls](docs/08-common-pitfalls.md) you may
|
|||
- [Browser testing](docs/recipes/browser-testing.md)
|
||||
- [TypeScript](docs/recipes/typescript.md)
|
||||
- [Flow](docs/recipes/flow.md)
|
||||
- [Configuring Babel][Babel recipe]
|
||||
- [Configuring Babel](https://github.com/avajs/babel)
|
||||
- [Using ES modules](docs/recipes/es-modules.md)
|
||||
- [Passing arguments to your test files](docs/recipes/passing-arguments-to-your-test-files.md)
|
||||
- [Testing React components](docs/recipes/react.md)
|
||||
|
|
@ -243,5 +233,3 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
|
|||
<br>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
[Babel recipe]: docs/recipes/babel.md
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
module.exports = require('@ava/babel/stage-4');
|
||||
533
test/api.js
533
test/api.js
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
require('../lib/chalk').set();
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const del = require('del');
|
||||
|
|
@ -10,71 +9,25 @@ const Api = require('../lib/api');
|
|||
const babelManager = require('../lib/babel-manager');
|
||||
const {normalizeGlobs} = require('../lib/globs');
|
||||
|
||||
const testCapitalizerPlugin = require.resolve('./fixture/babel-plugin-test-capitalizer');
|
||||
|
||||
const ROOT_DIR = path.join(__dirname, '..');
|
||||
|
||||
function withNodeEnv(value, run) {
|
||||
assert(!('NODE_ENV' in process.env));
|
||||
process.env.NODE_ENV = value;
|
||||
const reset = () => {
|
||||
delete process.env.NODE_ENV;
|
||||
};
|
||||
|
||||
const promise = new Promise(resolve => {
|
||||
resolve(run());
|
||||
});
|
||||
promise.then(reset, reset);
|
||||
return promise;
|
||||
}
|
||||
|
||||
function apiCreator(options = {}) {
|
||||
options.projectDir = options.projectDir || ROOT_DIR;
|
||||
options.babelProvider = babelManager({experiments: {}, projectDir: options.projectDir});
|
||||
options.babelProvider.validateConfig(options.babelConfig, options.compileEnhancements !== false);
|
||||
if (options.babelConfig !== undefined) {
|
||||
options.babelProvider = babelManager({projectDir: options.projectDir});
|
||||
options.babelProvider.validateConfig(options.babelConfig);
|
||||
}
|
||||
|
||||
options.concurrency = 2;
|
||||
options.extensions = options.extensions || {all: ['js'], enhancementsOnly: [], babelOnly: ['js']};
|
||||
options.experiments = {};
|
||||
options.globs = normalizeGlobs(options.files, options.helpers, options.sources, options.extensions.all);
|
||||
options.resolveTestsFrom = options.resolveTestsFrom || options.projectDir;
|
||||
const instance = new Api(options);
|
||||
if (!options.precompileHelpers) {
|
||||
instance._precompileHelpers = () => Promise.resolve();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
test('ES2015 support', t => {
|
||||
const api = apiCreator();
|
||||
|
||||
return api.run([path.join(__dirname, 'fixture/es2015.js')])
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('precompile helpers', t => {
|
||||
const api = apiCreator({
|
||||
precompileHelpers: true,
|
||||
resolveTestsFrom: path.join(__dirname, 'fixture/precompile-helpers')
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('async/await support', t => {
|
||||
const api = apiCreator();
|
||||
|
||||
return api.run([path.join(__dirname, 'fixture/async-await.js')])
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('test.meta.file', t => {
|
||||
const api = apiCreator();
|
||||
|
||||
|
|
@ -367,7 +320,7 @@ test('stack traces for exceptions are corrected using a source map file', t => {
|
|||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.match(evt.err.message, /Thrown by source-map-fixtures/);
|
||||
t.match(evt.err.stack, /^.*?Object\.run\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?\brun\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?Immediate\b.*source-map-file.js:4.*$/m);
|
||||
}
|
||||
});
|
||||
|
|
@ -379,33 +332,6 @@ test('stack traces for exceptions are corrected using a source map file', t => {
|
|||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions can disable sourceMaps', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
sourceMaps: false
|
||||
}
|
||||
},
|
||||
cacheEnabled: true
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.match(evt.err.message, /Thrown by source-map-fixtures/);
|
||||
t.match(evt.err.stack, /^.*?Immediate\b.*source-map-file.js:7.*$/m);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run([path.join(__dirname, 'fixture/source-map-file.js')])
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('stack traces for exceptions are corrected using a source map file in what looks like a browser env', t => {
|
||||
t.plan(4);
|
||||
|
||||
|
|
@ -417,7 +343,7 @@ test('stack traces for exceptions are corrected using a source map file in what
|
|||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.match(evt.err.message, /Thrown by source-map-fixtures/);
|
||||
t.match(evt.err.stack, /^.*?Object\.run\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?\brun\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?Immediate\b.*source-map-file-browser-env.js:7.*$/m);
|
||||
}
|
||||
});
|
||||
|
|
@ -453,7 +379,7 @@ test('enhanced assertion formatting necessary whitespace and empty strings', t =
|
|||
];
|
||||
|
||||
t.plan(15);
|
||||
const api = apiCreator();
|
||||
const api = apiCreator({babelConfig: true});
|
||||
const errors = [];
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
|
|
@ -486,7 +412,7 @@ test('stack traces for exceptions are corrected using a source map file (cache o
|
|||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.match(evt.err.message, /Thrown by source-map-fixtures/);
|
||||
t.match(evt.err.stack, /^.*?Object\.run\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?\brun\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?Immediate\b.*source-map-file.js:4.*$/m);
|
||||
}
|
||||
});
|
||||
|
|
@ -509,7 +435,7 @@ test('stack traces for exceptions are corrected using a source map, taking an in
|
|||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.match(evt.err.message, /Thrown by source-map-fixtures/);
|
||||
t.match(evt.err.stack, /^.*?Object\.t.*?\[?as run\]?\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?\brun\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?Immediate\b.*source-map-initial-input.js:14.*$/m);
|
||||
}
|
||||
});
|
||||
|
|
@ -532,7 +458,7 @@ test('stack traces for exceptions are corrected using a source map, taking an in
|
|||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.match(evt.err.message, /Thrown by source-map-fixtures/);
|
||||
t.match(evt.err.stack, /^.*?Object\.t.*?\[?as run\]?\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?\brun\b.*source-map-fixtures.src.throws.js:1.*$/m);
|
||||
t.match(evt.err.stack, /^.*?Immediate\b.*source-map-initial-input.js:14.*$/m);
|
||||
}
|
||||
});
|
||||
|
|
@ -616,6 +542,7 @@ test('caching is enabled by default', t => {
|
|||
del.sync(path.join(__dirname, 'fixture/caching/node_modules'));
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: true,
|
||||
projectDir: path.join(__dirname, 'fixture/caching')
|
||||
});
|
||||
|
||||
|
|
@ -716,442 +643,6 @@ test('verify test count', t => {
|
|||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions with a custom plugin', t => {
|
||||
t.plan(2);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
plugins: [testCapitalizerPlugin]
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: __dirname
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.is(evt.title, 'FOO');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run([path.join(__dirname, 'fixture/babelrc/test.js')])
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
}, t.threw);
|
||||
});
|
||||
|
||||
test('babel.testOptions.babelrc effectively defaults to true', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok((evt.title === 'foo') || (evt.title === 'repeated test: foo'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions.babelrc can explicitly be true', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {babelrc: true}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok(evt.title === 'foo' || evt.title === 'repeated test: foo');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions.babelrc can explicitly be false', t => {
|
||||
t.plan(2);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {babelrc: false}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.is(evt.title, 'foo');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions merges plugins with .babelrc', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
babelrc: true,
|
||||
plugins: [testCapitalizerPlugin]
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok(evt.title === 'FOO' || evt.title === 'repeated test: foo');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions.babelrc (when true) picks up .babelrc.js files', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
babelrc: true
|
||||
}
|
||||
},
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc-js')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok((evt.title === 'foo') || (evt.title === 'repeated test: foo'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions.configFile effectively defaults to true', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
projectDir: path.join(__dirname, 'fixture/babel-config')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok((evt.title === 'foo') || (evt.title === 'repeated test: foo'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions.configFile can explicitly be true', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {configFile: true}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babel-config')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok(evt.title === 'foo' || evt.title === 'repeated test: foo');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions.configFile can explicitly be false', t => {
|
||||
t.plan(2);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {configFile: false}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babel-config')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.is(evt.title, 'foo');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions merges plugins with babel.config.js', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
babelrc: true,
|
||||
plugins: [testCapitalizerPlugin]
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babel-config')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok(evt.title === 'FOO' || evt.title === 'repeated test: foo');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions can disable ava/stage-4', t => {
|
||||
t.plan(1);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
babelrc: false,
|
||||
presets: [[require.resolve('../stage-4'), false]]
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.is(evt.err.name, 'SyntaxError');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run();
|
||||
});
|
||||
|
||||
test('babel.testOptions with extends still merges plugins with .babelrc', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
plugins: [testCapitalizerPlugin],
|
||||
extends: path.join(__dirname, 'fixture/babelrc/.alt-babelrc')
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok(evt.title === 'BAR' || evt.title === 'repeated test: bar');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('babel.testOptions with extends still merges plugins with babel.config.js', t => {
|
||||
t.plan(3);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
plugins: [testCapitalizerPlugin],
|
||||
extends: path.join(__dirname, 'fixture/babel-config/.alt-babelrc')
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babel-config')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok(evt.title === 'BAR' || evt.title === 'repeated test: bar');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('extended config can disable ava/stage-4', t => {
|
||||
t.plan(1);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
babelrc: false,
|
||||
extends: path.join(__dirname, 'fixture/babelrc/disable-stage-4.babelrc')
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.is(evt.err.name, 'SyntaxError');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run();
|
||||
});
|
||||
|
||||
test('babel can be disabled for particular files', t => {
|
||||
t.plan(1);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
babelrc: false,
|
||||
ignore: [path.join(__dirname, 'fixture/babelrc/test.js')]
|
||||
}
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'uncaught-exception') {
|
||||
t.is(evt.err.name, 'SyntaxError');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run();
|
||||
});
|
||||
|
||||
test('uses "development" Babel environment if NODE_ENV is the empty string', t => {
|
||||
t.plan(2);
|
||||
|
||||
const api = apiCreator({
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/babelrc')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.is(evt.title, 'FOO');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return withNodeEnv('', () => api.run())
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('babelOnly extensions take precedence over enhancements-only', t => {
|
||||
t.plan(2);
|
||||
|
||||
const api = apiCreator({
|
||||
babelConfig: {
|
||||
testOptions: {
|
||||
plugins: [testCapitalizerPlugin]
|
||||
}
|
||||
},
|
||||
extensions: {
|
||||
all: ['foo.bar', 'bar'],
|
||||
enhancementsOnly: ['bar'],
|
||||
babelOnly: ['foo.bar']
|
||||
},
|
||||
cacheEnabled: false,
|
||||
projectDir: path.join(__dirname, 'fixture/extensions')
|
||||
});
|
||||
|
||||
api.on('run', plan => {
|
||||
plan.status.on('stateChange', evt => {
|
||||
if (evt.type === 'test-passed') {
|
||||
t.ok(evt.title === 'FOO');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return api.run()
|
||||
.then(runStatus => {
|
||||
t.is(runStatus.stats.passedTests, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('using --match with matching tests will only report those passing tests', t => {
|
||||
t.plan(3);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
import test from '../..';
|
||||
|
||||
test('async function', async t => {
|
||||
t.plan(1);
|
||||
const value = await Promise.resolve(1);
|
||||
t.is(value, 1);
|
||||
});
|
||||
|
||||
test('arrow async function', async t => {
|
||||
t.plan(1);
|
||||
const value = await Promise.resolve(1);
|
||||
t.is(value, 1);
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from 'ava';
|
||||
const test = require('ava');
|
||||
|
||||
test('test', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"plugins": ["../babel-plugin-foo-to-bar"]
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
module.exports = {
|
||||
presets: ['@ava/stage-4'],
|
||||
env: {
|
||||
development: {
|
||||
plugins: ['../babel-plugin-test-capitalizer']
|
||||
},
|
||||
test: {
|
||||
plugins: ['../babel-plugin-test-doubler']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"name": "application-name",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import test from '../../..';
|
||||
|
||||
test('foo', t => {
|
||||
// Using optional catch-binding to ensure it transpiles on Node.js 8, since this
|
||||
// is a Node.js 10 feature
|
||||
try {
|
||||
throw new Error('test');
|
||||
} catch {
|
||||
t.pass();
|
||||
}
|
||||
});
|
||||
|
|
@ -1 +0,0 @@
|
|||
export default () => {};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import './babel-hook-imported'; // eslint-disable-line import/no-unassigned-import
|
||||
|
|
@ -1 +0,0 @@
|
|||
module.exports = () => ({});
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
function isRequire(path) {
|
||||
return path.isCallExpression() && path.get('callee').isIdentifier() && (path.get('callee').node.name === 'require');
|
||||
}
|
||||
|
||||
module.exports = babel => {
|
||||
const t = babel.types;
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression: path => {
|
||||
// Skip require calls
|
||||
const firstArg = path.get('arguments')[0];
|
||||
|
||||
if (!isRequire(path) && firstArg && firstArg.isStringLiteral() && /foo/i.test(firstArg.node.value)) {
|
||||
firstArg.replaceWith(t.stringLiteral(firstArg.node.value.replace('foo', 'bar').replace('FOO', 'BAR')));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
function isRequire(path) {
|
||||
return path.isCallExpression() && path.get('callee').isIdentifier() && (path.get('callee').node.name === 'require');
|
||||
}
|
||||
|
||||
module.exports = babel => {
|
||||
const t = babel.types;
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression: path => {
|
||||
// Skip require calls
|
||||
const firstArg = path.get('arguments')[0];
|
||||
|
||||
if (!isRequire(path) && firstArg && firstArg.isStringLiteral() && !firstArg.node.value.includes('repeated test')) {
|
||||
firstArg.replaceWith(t.stringLiteral(firstArg.node.value.toUpperCase()));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* eslint-disable new-cap */
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
A Babel plugin that causes each AVA test to be duplicated with a new title.
|
||||
|
||||
test('foo', t => {});
|
||||
|
||||
becomes
|
||||
|
||||
test('foo', t => {});
|
||||
test('repeated test: foo', t => {});
|
||||
|
||||
This is used by some integration tests to validate correct handling of Babel config options.
|
||||
*/
|
||||
module.exports = babel => {
|
||||
const t = babel.types;
|
||||
let anonCount = 1;
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression: path => {
|
||||
const {node} = path;
|
||||
const {callee} = node;
|
||||
let args = node.arguments;
|
||||
|
||||
if (callee.type === 'Identifier' && callee.name === 'test') {
|
||||
if (args.length === 1) {
|
||||
args = [t.StringLiteral(`repeated test: anonymous${anonCount++}`), args[0]];
|
||||
} else if (args.length === 2 && args[0].type === 'StringLiteral') {
|
||||
if (args[0].value.startsWith('repeated test')) {
|
||||
return;
|
||||
}
|
||||
|
||||
args = args.slice();
|
||||
args[0] = t.StringLiteral(`repeated test: ${args[0].value}`);
|
||||
} else {
|
||||
throw new Error('The plugin does not know how to handle this call to test');
|
||||
}
|
||||
|
||||
path.insertAfter(t.CallExpression(
|
||||
t.Identifier('test'),
|
||||
args
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
module.exports = api => {
|
||||
api.cache.forever();
|
||||
return {
|
||||
'plugins': ['../babel-plugin-test-doubler'],
|
||||
'presets': ['@ava/stage-4']
|
||||
};
|
||||
};
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"name": "application-name",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import test from '../../..';
|
||||
|
||||
test('foo', t => {
|
||||
// Using optional catch-binding to ensure it transpiles on Node.js 8, since this
|
||||
// is a Node.js 10 feature
|
||||
try {
|
||||
throw new Error('test');
|
||||
} catch {
|
||||
t.pass();
|
||||
}
|
||||
});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"plugins": ["../babel-plugin-foo-to-bar"]
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"presets": ["@ava/stage-4"],
|
||||
"env": {
|
||||
"development": {
|
||||
"plugins": ["../babel-plugin-test-capitalizer"]
|
||||
},
|
||||
"test": {
|
||||
"plugins": ["../babel-plugin-test-doubler"],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"presets": [["../../../stage-4", false]]
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"name": "application-name",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import test from '../../..';
|
||||
|
||||
test('foo', t => {
|
||||
// Using optional catch-binding to ensure it transpiles on Node.js 8, since this
|
||||
// is a Node.js 10 feature
|
||||
try {
|
||||
throw new Error('test');
|
||||
} catch {
|
||||
t.pass();
|
||||
}
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
t.true(2 + 2 === 4);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('works', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
{}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import test from '../../../../../..';
|
||||
|
||||
test('ok', t => t.pass());
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
const foo = 'foo';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import test from '../../..';
|
||||
import {name, value} from '.';
|
||||
const test = require('../../..');
|
||||
const {name, value} = require('.');
|
||||
|
||||
test('works', t => {
|
||||
t.is(process.env[name], value);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
const getAnonymousFn = () => () => {
|
||||
throw new Error(); // eslint-disable-line unicorn/error-message
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import test from '../..';
|
||||
|
||||
test('test', t => {
|
||||
t.pass();
|
||||
});
|
||||
|
||||
// eslint-disable-next-line spaced-comment
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzMjAxNS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxRQUFRLENBQUM7O0FBRTFCLElBQUksQ0FBQyxDQUFDLElBQUk7QUFDVCxFQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7Q0FDVCxDQUFDLENBQUMiLCJmaWxlIjoiZXMyMDE1LXNvdXJjZS1tYXBzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHRlc3QgZnJvbSAnLi4vLi4vJztcblxudGVzdCh0ID0+IHtcblx0dC5wYXNzKCk7XG59KTtcbiJdfQ==
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
test('test', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export default {
|
||||
babel: false,
|
||||
extensions: ['foo'],
|
||||
files: ['tests/**/*'],
|
||||
helpers: ['helpers/*']
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
const one = {one: 1};
|
||||
const two = {two: 2};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
import '../../../..'; // eslint-disable-line import/no-unassigned-import
|
||||
require('../../../..'); // eslint-disable-line import/no-unassigned-import
|
||||
|
||||
process.exit(1); // eslint-disable-line unicorn/no-process-exit
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test('first pass', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test('first pass', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test.serial('first pass', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test('first pass', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test('first pass', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test.cb('slow pass', t => {
|
||||
setTimeout(t.end, 1000);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test('first pass', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test('pass', t => t.pass());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
setTimeout(() => {
|
||||
test.serial('pass', t => t.pass());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
test('test', t => {
|
||||
t.deepEqual({foo: 1}, {foo: 2});
|
||||
|
|
|
|||
|
|
@ -1,336 +0,0 @@
|
|||
import React from 'react';
|
||||
import test from '../..';
|
||||
import HelloMessage from './hello-message';
|
||||
|
||||
// Older AVA versions that do not use Concordance don't handle globals very
|
||||
// well. Use this so formatting output can be contrasted between versions.
|
||||
const formatGlobals = Boolean(require(process.env.AVA_PATH + '/package.json').dependencies.concordance);
|
||||
|
||||
test('date formatted', t => {
|
||||
const date = new Date('1969-07-20T20:17:40.000Z');
|
||||
t.true(date);
|
||||
});
|
||||
test('invalid date formatted', t => {
|
||||
const date = new Date('🙀');
|
||||
t.true(date);
|
||||
});
|
||||
test('date formatted, subclass', t => {
|
||||
class Foo extends Date {}
|
||||
const date = new Foo('1969-07-20T20:17:40.000Z');
|
||||
t.true(date);
|
||||
});
|
||||
test('date diff', t => {
|
||||
t.deepEqual(new Date('1969-07-20T20:17:40.000Z'), new Date());
|
||||
});
|
||||
test('date diff, extra properties', t => {
|
||||
t.deepEqual(new Date('1969-07-20T20:17:40.000Z'), Object.assign(new Date('1969-07-20T20:17:40.000Z'), {
|
||||
foo: 'bar'
|
||||
}));
|
||||
});
|
||||
|
||||
test('error formatted', t => {
|
||||
const err = new Error('Houston, we have a problem');
|
||||
t.true(err);
|
||||
});
|
||||
test('error formatted, constructor does not match name', t => {
|
||||
const err = Object.assign(new Error('Houston, we have a problem'), {name: 'FamousWords'});
|
||||
t.true(err);
|
||||
});
|
||||
test('error formatted, constructor does not match name, and string tag does not match constructor', t => {
|
||||
class CustomError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'FamousWords';
|
||||
}
|
||||
}
|
||||
const err = new CustomError('Houston, we have a problem');
|
||||
t.true(err);
|
||||
});
|
||||
test('error formatted, no name or constructor', t => {
|
||||
class CustomError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = '';
|
||||
}
|
||||
}
|
||||
const err = new CustomError('Houston, we have a problem');
|
||||
Object.defineProperty(err, 'constructor', {});
|
||||
t.true(err);
|
||||
});
|
||||
test('error diff, message', t => {
|
||||
t.deepEqual(new Error('Houston, we have a problem'), new Error('One small step'));
|
||||
});
|
||||
test('error diff, constructor', t => {
|
||||
t.deepEqual(new Error('Houston, we have a problem'), new RangeError('One small step'));
|
||||
});
|
||||
test('error diff, extra properties', t => {
|
||||
t.deepEqual(new Error('Houston, we have a problem'), Object.assign(new Error('Houston, we have a problem'), {
|
||||
date: new Date('1969-07-20T20:17:40.000Z')
|
||||
}));
|
||||
});
|
||||
test('error thrown in test', () => {
|
||||
throw Object.assign(new Error('Houston, we have a problem'), {
|
||||
date: new Date('1969-07-20T20:17:40.000Z')
|
||||
});
|
||||
});
|
||||
test.cb('callback test ended with error', t => {
|
||||
t.end(Object.assign(new Error('Houston, we have a problem'), {
|
||||
date: new Date('1969-07-20T20:17:40.000Z')
|
||||
}));
|
||||
});
|
||||
test('error thrown in test due to improper throws', t => {
|
||||
const improper = () => {
|
||||
throw Object.assign(new Error('Houston, we have a problem'), {
|
||||
date: new Date('1969-07-20T20:17:40.000Z')
|
||||
});
|
||||
};
|
||||
|
||||
t.throws(improper());
|
||||
});
|
||||
test('test returned rejected promise', () => {
|
||||
return Promise.reject(Object.assign(new Error('Houston, we have a problem'), {
|
||||
date: new Date('1969-07-20T20:17:40.000Z')
|
||||
}));
|
||||
});
|
||||
|
||||
test('array of strings formatted', t => {
|
||||
const arr = ['foo'];
|
||||
t.true(arr);
|
||||
});
|
||||
test('array of strings diff', t => {
|
||||
t.deepEqual(['foo'], ['bar']);
|
||||
});
|
||||
|
||||
test('string formatted', t => {
|
||||
t.true('foo');
|
||||
});
|
||||
test('string diff', t => {
|
||||
t.is('foo', 'bar');
|
||||
});
|
||||
test('string diff, with overlap', t => {
|
||||
t.is('foobar', 'bar');
|
||||
});
|
||||
test('multiline string diff, with overlap at start', t => {
|
||||
t.is('foo\nbar', 'foo\nbaz');
|
||||
});
|
||||
test('multiline string diff, with overlap at end', t => {
|
||||
t.is('bar\nbaz', 'foo\nbaz');
|
||||
});
|
||||
|
||||
test('map formatted', t => {
|
||||
const map = new Map([['foo', 'bar']]);
|
||||
t.true(map);
|
||||
});
|
||||
test('map diff', t => {
|
||||
t.deepEqual(new Map([['foo', 'bar']]), new Map([['baz', 'qux']]));
|
||||
});
|
||||
test('map diff, extra properties', t => {
|
||||
t.deepEqual(new Map([['foo', 'bar']]), Object.assign(new Map([['foo', 'bar']]), {baz: 'qux'}));
|
||||
});
|
||||
|
||||
test('function formatted', t => {
|
||||
const fn = function foo() {}; // eslint-disable-line func-name-matching, func-names
|
||||
t.true(fn);
|
||||
});
|
||||
test('function diff', t => {
|
||||
function foo() {}
|
||||
function bar() {}
|
||||
t.deepEqual(foo, bar);
|
||||
});
|
||||
test('function diff, extra properties', t => {
|
||||
function foo() {}
|
||||
function bar() {}
|
||||
t.deepEqual(foo, Object.assign(bar, {baz: 'qux'}));
|
||||
});
|
||||
test('anonymous function', t => {
|
||||
t.true(() => {});
|
||||
});
|
||||
test('generator function', t => {
|
||||
t.true(function * foo() {}); // eslint-disable-line func-names
|
||||
});
|
||||
|
||||
/* eslint-disable prefer-rest-params */
|
||||
test('arguments formatted', t => {
|
||||
const args = (function () {
|
||||
return arguments;
|
||||
})('foo');
|
||||
t.true(args);
|
||||
});
|
||||
test('arguments diff', t => {
|
||||
const foo = (function () {
|
||||
return arguments;
|
||||
})('foo');
|
||||
const bar = (function () {
|
||||
return arguments;
|
||||
})('bar');
|
||||
t.deepEqual(foo, bar);
|
||||
});
|
||||
test('arguments diff with normal array', t => {
|
||||
const foo = (function () {
|
||||
return arguments;
|
||||
})('foo');
|
||||
t.deepEqual(foo, ['bar']);
|
||||
});
|
||||
/* eslint-enable prefer-rest-params */
|
||||
|
||||
if (formatGlobals) {
|
||||
test('global formatted', t => {
|
||||
t.true(global);
|
||||
});
|
||||
test('global diff', t => {
|
||||
t.deepEqual(global, {});
|
||||
});
|
||||
}
|
||||
|
||||
test('object formatted', t => {
|
||||
const obj = {
|
||||
foo: 'bar'
|
||||
};
|
||||
t.true(obj);
|
||||
});
|
||||
test('object diff', t => {
|
||||
t.deepEqual({
|
||||
foo: 'bar'
|
||||
}, {
|
||||
baz: 'qux'
|
||||
});
|
||||
});
|
||||
test('object formatted, custom class', t => {
|
||||
class Foo {}
|
||||
const obj = new Foo();
|
||||
t.true(obj);
|
||||
});
|
||||
test('object formatted, no constructor', t => {
|
||||
class Foo {}
|
||||
const obj = new Foo();
|
||||
Object.defineProperty(obj, 'constructor', {});
|
||||
t.true(obj);
|
||||
});
|
||||
test('object formatted, non-Object string tag that does not match constructor', t => {
|
||||
class Foo extends Array {}
|
||||
const obj = new Foo();
|
||||
t.true(obj);
|
||||
});
|
||||
|
||||
test('promise formatted', t => {
|
||||
const promise = Promise.resolve();
|
||||
t.true(promise);
|
||||
});
|
||||
test('promise diff', t => {
|
||||
t.deepEqual(Promise.resolve(), Promise.resolve());
|
||||
});
|
||||
test('promise diff, extra properties', t => {
|
||||
t.deepEqual(Promise.resolve(), Object.assign(Promise.resolve(), {foo: 'bar'}));
|
||||
});
|
||||
|
||||
test('regexp formatted', t => {
|
||||
const regexp = /foo/gi;
|
||||
t.true(regexp);
|
||||
});
|
||||
test('regexp diff', t => {
|
||||
t.deepEqual(/foo/gi, /bar/gi);
|
||||
});
|
||||
test('regexp diff, extra properties', t => {
|
||||
t.deepEqual(/foo/gi, Object.assign(/foo/gi, {baz: 'qux'}));
|
||||
});
|
||||
|
||||
test('set formatted', t => {
|
||||
const set = new Set([{foo: 'bar'}]);
|
||||
t.true(set);
|
||||
});
|
||||
test('set diff, string values', t => {
|
||||
t.deepEqual(new Set(['foo']), new Set(['bar']));
|
||||
});
|
||||
test('set diff, object values', t => {
|
||||
t.deepEqual(new Set([{foo: 'bar'}]), new Set([{bar: 'baz'}]));
|
||||
});
|
||||
test('set diff, distinct values', t => {
|
||||
t.deepEqual(new Set([{foo: 'bar'}]), new Set([null]));
|
||||
});
|
||||
test('set diff, extra properties', t => {
|
||||
t.deepEqual(new Set([{foo: 'bar'}]), Object.assign(new Set([{foo: 'bar'}]), {baz: 'qux'}));
|
||||
});
|
||||
|
||||
test('buffer formatted', t => {
|
||||
const buffer = Buffer.from('decafba'.repeat(12), 'hex');
|
||||
t.true(buffer);
|
||||
});
|
||||
test('buffer diff', t => {
|
||||
t.deepEqual(Buffer.from('decafba'.repeat(12), 'hex'), Buffer.from('baddecaf', 'hex'));
|
||||
});
|
||||
test('buffer diff, extra properties', t => {
|
||||
t.deepEqual(Buffer.from('decafba'.repeat(12), 'hex'), Object.assign(Buffer.from('decafba'.repeat(12), 'hex'), {foo: 'bar'}));
|
||||
});
|
||||
|
||||
test('primitives', t => {
|
||||
const primitives = [
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
0,
|
||||
-0,
|
||||
42,
|
||||
Infinity,
|
||||
-Infinity,
|
||||
NaN,
|
||||
'foo',
|
||||
'foo\nbar',
|
||||
Symbol.iterator,
|
||||
Symbol.for('foo'),
|
||||
Symbol('bar'),
|
||||
undefined
|
||||
];
|
||||
t.true(primitives);
|
||||
});
|
||||
|
||||
test('circular references', t => {
|
||||
const obj = {};
|
||||
obj.circular = obj;
|
||||
t.true(obj);
|
||||
});
|
||||
|
||||
test('react element, formatted', t => {
|
||||
const element = React.createElement(HelloMessage, {name: 'Sindre'});
|
||||
t.true(element);
|
||||
});
|
||||
test('react element, complex attributes, formatted', t => {
|
||||
const element = React.createElement('div', {
|
||||
multiline: 'Hello\nworld',
|
||||
object: {foo: ['bar']}
|
||||
});
|
||||
t.true(element);
|
||||
});
|
||||
test('react element, opaque children, formatted', t => {
|
||||
const element = React.createElement('Foo', null, new Set(['foo']), true);
|
||||
t.true(element);
|
||||
});
|
||||
test('react element, diff', t => {
|
||||
const element = React.createElement(HelloMessage, {name: 'Sindre'});
|
||||
const other = React.createElement(HelloMessage, {name: 'Vadim'});
|
||||
t.deepEqual(element, other);
|
||||
});
|
||||
|
||||
test('deep structure, formatted', t => {
|
||||
const deep = {
|
||||
foo: {
|
||||
bar: {
|
||||
baz: {
|
||||
qux: 'quux'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
t.true(deep);
|
||||
});
|
||||
test('deep structure, diff', t => {
|
||||
const deep = {
|
||||
foo: {
|
||||
bar: {
|
||||
baz: {
|
||||
qux: 'quux'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
t.deepEqual(deep, {corge: 'grault', ...deep});
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
test.before(() => {
|
||||
throw new Error('should not run');
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../../..';
|
||||
const test = require('../../../..');
|
||||
|
||||
test('test', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('pass', t => t.pass());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test.cb('test', t => {
|
||||
setTimeout(() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
try {
|
||||
|
|
|
|||
5
test/fixture/improper-t-throws/package.json
Normal file
5
test/fixture/improper-t-throws/package.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"ava": {
|
||||
"babel": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
return Promise.resolve().then(() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
t.throws(throwSync());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../../..';
|
||||
const test = require('../../..');
|
||||
|
||||
test.cb('test', t => {
|
||||
Promise.resolve().then(() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
Error.stackTraceLimit = 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
import test from '../..';
|
||||
|
||||
test('test', t => {
|
||||
t.true(process.execArgv[0].startsWith('--inspect'));
|
||||
});
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"ava": {
|
||||
"babel": {
|
||||
"extensions": ["js", "js", "jsx", "jsx"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"ava": {
|
||||
"babel": false,
|
||||
"extensions": ["js", "js", "jsx", "jsx"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
import dependency from './dependency'; // eslint-disable-line no-unused-vars
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"ava": {
|
||||
"extensions": ["foo"]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('../../../..');
|
||||
|
||||
test('test', t => {
|
||||
const bool = false;
|
||||
t.assert(bool);
|
||||
});
|
||||
|
|
@ -1 +0,0 @@
|
|||
import dependency from './dependency'; // eslint-disable-line no-unused-vars
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"ava": {
|
||||
"babel": false,
|
||||
"compileEnhancements": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('../../..');
|
||||
|
||||
test('test', t => {
|
||||
const bool = false;
|
||||
t.assert(bool);
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
test.cb('slow', t => {
|
||||
setTimeout(t.end, 5000);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import test from '../../..';
|
||||
import Bluebird from './_enable-trace';
|
||||
const test = require('../../..');
|
||||
const Bluebird = require('./_enable-trace');
|
||||
|
||||
// This promise throwing pattern was used in bluebird documentation for long stack traces
|
||||
// http://bluebirdjs.com/docs/api/promise.longstacktraces.html
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import test from '../..';
|
||||
const test = require('../..');
|
||||
|
||||
test('this test will match', t => {
|
||||
t.pass();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue