From ba855b6fb0c003db0c3d05824ddb222d4fa20a2a Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Tue, 14 Jun 2016 17:20:27 -0500 Subject: [PATCH 01/14] Document common pitfalls --- docs/common-pitfalls.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/common-pitfalls.md diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md new file mode 100644 index 000000000..7357fd784 --- /dev/null +++ b/docs/common-pitfalls.md @@ -0,0 +1,7 @@ +# Common Pitfalls + +## 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 [https://github.com/avajs/ava/issues/751](#751). + +AVA uses [is-ci](https://github.com/watson/is-ci) to decided if it's in a CI environment or not using [these](https://github.com/watson/is-ci/blob/master/index.js) variables. From 0db5273678b6f9853ee435cdc67a2bdd583525e3 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Tue, 14 Jun 2016 17:25:37 -0500 Subject: [PATCH 02/14] Fix typo --- docs/common-pitfalls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md index 7357fd784..d39836b14 100644 --- a/docs/common-pitfalls.md +++ b/docs/common-pitfalls.md @@ -4,4 +4,4 @@ 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 [https://github.com/avajs/ava/issues/751](#751). -AVA uses [is-ci](https://github.com/watson/is-ci) to decided if it's in a CI environment or not using [these](https://github.com/watson/is-ci/blob/master/index.js) variables. +AVA uses [is-ci](https://github.com/watson/is-ci) to decide if it's in a CI environment or not using [these](https://github.com/watson/is-ci/blob/master/index.js) variables. From 129e806ebfa6ef7f94f848ccfc0dd5f0780965e5 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Fri, 17 Jun 2016 18:11:18 -0500 Subject: [PATCH 03/14] Document AVA and connected client limits --- docs/common-pitfalls.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md index d39836b14..23eed8c97 100644 --- a/docs/common-pitfalls.md +++ b/docs/common-pitfalls.md @@ -5,3 +5,9 @@ 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 [https://github.com/avajs/ava/issues/751](#751). AVA uses [is-ci](https://github.com/watson/is-ci) to decide if it's in a CI environment or not using [these](https://github.com/watson/is-ci/blob/master/index.js) variables. + +## AVA and connected client limits + +You may be using a service that only allows a limited number of concurrent connections. For example, many database-as-a-service businesses offer a free plan with a limit on how many clients can be using it at the same time. AVA can hit those limits and cause the tests to hang because it runs multiple processes, each of which is a different client. + +To fix this, use the `concurrency` flag to limit the number of processes ran. For example, if your service plan allows 5 clients, you should run AVA with `concurrency=5` or less. From d663cd6711d21a1804d722004fe53b90b3ec311d Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Sat, 18 Jun 2016 19:23:00 -0500 Subject: [PATCH 04/14] Update AVA and connected client limits --- docs/common-pitfalls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md index 23eed8c97..a19859550 100644 --- a/docs/common-pitfalls.md +++ b/docs/common-pitfalls.md @@ -8,6 +8,6 @@ AVA uses [is-ci](https://github.com/watson/is-ci) to decide if it's in a CI envi ## AVA and connected client limits -You may be using a service that only allows a limited number of concurrent connections. For example, many database-as-a-service businesses offer a free plan with a limit on how many clients can be using it at the same time. AVA can hit those limits and cause the tests to hang because it runs multiple processes, each of which is a different client. +You may be using a service that only allows a limited number of concurrent connections. For example, many database-as-a-service businesses offer a free plan with a limit on how many clients can be using it at the same time. AVA can hit those limits as it runs multiple processes, but well-written services should emit an error or throttle in those cases. If the one you're using doesn't, the tests will hang. -To fix this, use the `concurrency` flag to limit the number of processes ran. For example, if your service plan allows 5 clients, you should run AVA with `concurrency=5` or less. +Use the `concurrency` flag to limit the number of processes ran. For example, if your service plan allows 5 clients, you should run AVA with `concurrency=5` or less. From a777ffd8487d268768dfd7988fa5d863b453afac Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Sun, 19 Jun 2016 10:42:56 -0500 Subject: [PATCH 05/14] Add call for others to contribute --- docs/common-pitfalls.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md index a19859550..1ac1c7292 100644 --- a/docs/common-pitfalls.md +++ b/docs/common-pitfalls.md @@ -11,3 +11,8 @@ AVA uses [is-ci](https://github.com/watson/is-ci) to decide if it's in a CI envi You may be using a service that only allows a limited number of concurrent connections. For example, many database-as-a-service businesses offer a free plan with a limit on how many clients can be using it at the same time. AVA can hit those limits as it runs multiple processes, but well-written services should emit an error or throttle in those cases. If the one you're using doesn't, the tests will hang. Use the `concurrency` flag to limit the number of processes ran. For example, if your service plan allows 5 clients, you should run AVA with `concurrency=5` or less. + +--- + +Is your problem not listed here? Submit a pull request or comment on [this](https://github.com/avajs/ava/issues/404) issue. + From c9fa25c6e29a3585f2d72ea3de61f2a03b1eb120 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Sun, 19 Jun 2016 10:49:06 -0500 Subject: [PATCH 06/14] Document async operations --- docs/common-pitfalls.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md index 1ac1c7292..e5e572047 100644 --- a/docs/common-pitfalls.md +++ b/docs/common-pitfalls.md @@ -12,6 +12,28 @@ You may be using a service that only allows a limited number of concurrent conne Use the `concurrency` flag to limit the number of processes ran. For example, if your service plan allows 5 clients, you should run AVA with `concurrency=5` or less. +## Async operations + +You may be running an async operation inside a test and wondering why it's not finishing. If your async operation uses promises, you should be returning the promise: + +```js +test(t => { + return fetch().then(data => { + t.is(data, 'foo'); + }); +}); +``` + +If it uses callbacks, use [`test.cb`](https://github.com/avajs/ava#callback-support): + +```js +test.cb(t => { + fetch((err, data) => { + t.is(data, 'bar'); + }); +}); +``` + --- Is your problem not listed here? Submit a pull request or comment on [this](https://github.com/avajs/ava/issues/404) issue. From da9c034d8678de238115013dbee4917eef40e9f0 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Wed, 22 Jun 2016 09:39:23 -0400 Subject: [PATCH 07/14] Various improvements --- docs/common-pitfalls.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md index e5e572047..cc5f19195 100644 --- a/docs/common-pitfalls.md +++ b/docs/common-pitfalls.md @@ -4,7 +4,7 @@ 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 [https://github.com/avajs/ava/issues/751](#751). -AVA uses [is-ci](https://github.com/watson/is-ci) to decide if it's in a CI environment or not using [these](https://github.com/watson/is-ci/blob/master/index.js) variables. +AVA uses [is-ci](https://github.com/watson/is-ci) to decide if it's in a CI environment or not using [these variables](https://github.com/watson/is-ci/blob/master/index.js). ## AVA and connected client limits @@ -14,7 +14,7 @@ Use the `concurrency` flag to limit the number of processes ran. For example, if ## Async operations -You may be running an async operation inside a test and wondering why it's not finishing. If your async operation uses promises, you should be returning the promise: +You may be running an async operation inside a test and wondering why it's not finishing. If your async operation uses promises, you should return the promise: ```js test(t => { @@ -30,11 +30,13 @@ If it uses callbacks, use [`test.cb`](https://github.com/avajs/ava#callback-supp test.cb(t => { fetch((err, data) => { t.is(data, 'bar'); + t.end(); }); }); ``` ---- +Alternatively, promisify the promise using something like [pify](https://github.com/sindresorhus/pify). -Is your problem not listed here? Submit a pull request or comment on [this](https://github.com/avajs/ava/issues/404) issue. +--- +Is your problem not listed here? Submit a pull request or comment on [this issue](https://github.com/avajs/ava/issues/404). From 96685ba675b9e137c747855a092d11a7c690cd99 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Thu, 23 Jun 2016 09:38:40 -0400 Subject: [PATCH 08/14] Fix wrong word --- docs/common-pitfalls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/common-pitfalls.md b/docs/common-pitfalls.md index cc5f19195..5e1ad1d73 100644 --- a/docs/common-pitfalls.md +++ b/docs/common-pitfalls.md @@ -35,7 +35,7 @@ test.cb(t => { }); ``` -Alternatively, promisify the promise using something like [pify](https://github.com/sindresorhus/pify). +Alternatively, promisify the callback function using something like [pify](https://github.com/sindresorhus/pify). --- From 349543facc81329e7b2a7ad4e47a7bfce220f280 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Sat, 25 Jun 2016 12:00:49 -0400 Subject: [PATCH 09/14] Link from the readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index c2f0dfecf..b9ed7648b 100644 --- a/readme.md +++ b/readme.md @@ -1008,6 +1008,7 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy). - [Stack Overflow](https://stackoverflow.com/questions/tagged/ava) - [Gitter chat](https://gitter.im/avajs/ava) - [Twitter](https://twitter.com/ava__js) +- [Common pitfalls](https://github.com/avajs/ava/blob/master/docs/common-pitfalls.md) ## Related From 64348041e03a15bb4a9ab890e7cbf883e99d613a Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Sat, 25 Jun 2016 16:04:37 -0400 Subject: [PATCH 10/14] Move common pitfalls link to Tips --- readme.md | 137 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 67 deletions(-) diff --git a/readme.md b/readme.md index b9ed7648b..4a0c43a07 100644 --- a/readme.md +++ b/readme.md @@ -68,13 +68,13 @@ $ ava --init ```json { - "name": "awesome-package", - "scripts": { - "test": "ava" - }, - "devDependencies": { - "ava": "^0.11.0" - } + "name": "awesome-package", + "scripts": { + "test": "ava" + }, + "devDependencies": { + "ava": "^0.11.0" + } } ``` @@ -132,33 +132,33 @@ AVA comes with an intelligent watch mode. [Learn more in its recipe](docs/recipe ```console $ ava --help - Usage - ava [ ...] - - Options - --init Add AVA to your project - --fail-fast Stop after first test failure - --serial, -s Run tests serially - --require, -r Module to preload (Can be repeated) - --tap, -t Generate TAP output - --verbose, -v Enable verbose output - --no-cache Disable the transpiler cache - --match, -m Only run tests with matching title (Can be repeated) - --watch, -w Re-run tests when tests and source files change - --source, -S Pattern to match source files so tests can be re-run (Can be repeated) - --timeout, -T Set global timeout - --concurrency, -c Maximum number of test files running at the same time (EXPERIMENTAL) - - Examples - ava - ava test.js test2.js - ava test-*.js - ava test - ava --init - ava --init foo.js - - Default patterns when no arguments: - test.js test-*.js test/**/*.js **/__tests__/**/*.js **/*.test.js + Usage + ava [ ...] + + Options + --init Add AVA to your project + --fail-fast Stop after first test failure + --serial, -s Run tests serially + --require, -r Module to preload (Can be repeated) + --tap, -t Generate TAP output + --verbose, -v Enable verbose output + --no-cache Disable the transpiler cache + --match, -m Only run tests with matching title (Can be repeated) + --watch, -w Re-run tests when tests and source files change + --source, -S Pattern to match source files so tests can be re-run (Can be repeated) + --timeout, -T Set global timeout + --concurrency, -c Maximum number of test files running at the same time (EXPERIMENTAL) + + Examples + ava + ava test.js test2.js + ava test-*.js + ava test + ava --init + ava --init foo.js + + Default patterns when no arguments: + test.js test-*.js test/**/*.js **/__tests__/**/*.js **/*.test.js ``` *Note that the CLI will use your local install of AVA when available, even when run globally.* @@ -173,27 +173,27 @@ All of the CLI options can be configured in the `ava` section of your `package.j ```json { - "ava": { - "files": [ - "my-test-folder/*.js", - "!**/not-this-file.js" - ], - "source": [ - "**/*.{js,jsx}", - "!dist/**/*" - ], - "match": [ - "*oo", - "!foo" - ], - "concurrency": 5, - "failFast": true, - "tap": true, - "require": [ - "babel-register" - ], - "babel": "inherit" - } + "ava": { + "files": [ + "my-test-folder/*.js", + "!**/not-this-file.js" + ], + "source": [ + "**/*.{js,jsx}", + "!dist/**/*" + ], + "match": [ + "*oo", + "!foo" + ], + "concurrency": 5, + "failFast": true, + "tap": true, + "require": [ + "babel-register" + ], + "babel": "inherit" + } } ``` @@ -610,14 +610,14 @@ The corresponding Babel config for AVA's setup is as follows: ```json { - "presets": [ - "es2015", - "stage-2" - ], - "plugins": [ - "espower", - "transform-runtime" - ] + "presets": [ + "es2015", + "stage-2" + ], + "plugins": [ + "espower", + "transform-runtime" + ] } ``` @@ -935,9 +935,9 @@ Will output: ``` t.true(a.test(b) || b === c) - | | | | - | "bar" "bar" "baz" - false + | | | | + | "bar" "bar" "baz" + false ``` ## Process isolation @@ -966,6 +966,10 @@ You can't use [`istanbul`](https://github.com/gotwarlost/istanbul) for code cove As of version `5.0.0` it uses source maps to report coverage for your actual code, regardless of transpilation. Make sure that the code you're testing includes an inline source map or references a source map file. If you use `babel-register` you can set the `sourceMaps` option in your Babel config to `inline`. +### Common pitfalls + +We have a growing list of [common pitfalls](https://github.com/avajs/ava/blob/master/docs/common-pitfalls.md) you may experience while using AVA. If you encounter any issues you think are common, comment on [this issue](https://github.com/avajs/ava/issues/404). + ## FAQ ### Why not `mocha`, `tape`, `tap`? @@ -1008,7 +1012,6 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy). - [Stack Overflow](https://stackoverflow.com/questions/tagged/ava) - [Gitter chat](https://gitter.im/avajs/ava) - [Twitter](https://twitter.com/ava__js) -- [Common pitfalls](https://github.com/avajs/ava/blob/master/docs/common-pitfalls.md) ## Related From 10cb03b5bfa39b6c13bdf57b5dc3bd1aee043052 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Sun, 26 Jun 2016 13:48:53 -0400 Subject: [PATCH 11/14] Make common pitfalls link relative --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 4a0c43a07..89689f73c 100644 --- a/readme.md +++ b/readme.md @@ -968,7 +968,7 @@ As of version `5.0.0` it uses source maps to report coverage for your actual cod ### Common pitfalls -We have a growing list of [common pitfalls](https://github.com/avajs/ava/blob/master/docs/common-pitfalls.md) you may experience while using AVA. If you encounter any issues you think are common, comment on [this issue](https://github.com/avajs/ava/issues/404). +We have a growing list of [common pitfalls](docs/common-pitfalls.md) you may experience while using AVA. If you encounter any issues you think are common, comment on [this issue](https://github.com/avajs/ava/issues/404). ## FAQ From 6d71cbe8f6c31c7fe80dde6a1c4d1994a03d2b89 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Sun, 26 Jun 2016 14:03:23 -0400 Subject: [PATCH 12/14] Attempt to fix more merge conflict stuff --- api.js | 18 +- bench/run.js | 19 +- cli.js | 27 +- docs/recipes/react.md | 3 +- docs/recipes/watch-mode.md | 7 +- index.js | 2 +- lib/assert.js | 7 +- lib/ava-files.js | 262 ------------- lib/babel-config.js | 146 ++++++++ lib/caching-precompiler.js | 102 +---- lib/enhance-assert.js | 12 +- lib/logger.js | 2 +- lib/test-worker.js | 8 +- lib/test.js | 14 +- lib/throws-helper.js | 4 +- lib/watcher.js | 19 +- package.json | 22 +- profile.js | 7 +- test/assert.js | 46 ++- test/ava-files.js | 143 ------- test/babel-config.js | 50 +++ test/caching-precompiler.js | 30 -- test/cli.js | 160 ++++---- test/concurrent.js | 353 ++++++++++++++---- .../sub/directory/__tests__/_foo.js | 1 - .../sub/directory/__tests__/fixtures/foo.js | 1 - .../sub/directory/__tests__/foo.js | 1 - .../sub/directory/__tests__/helpers/foo.js | 1 - .../sub/directory/bar.test.js | 1 - .../ava-files/default-patterns/test-foo.js | 1 - .../ava-files/default-patterns/test.js | 1 - .../default-patterns/test/_foo-help.js | 1 - .../ava-files/default-patterns/test/baz.js | 1 - .../default-patterns/test/deep/deep.js | 1 - .../test/fixtures/foo-fixt.js | 1 - .../default-patterns/test/helpers/test.js | 1 - .../ava-files/no-duplicates/lib/bar.js | 1 - .../ava-files/no-duplicates/lib/foo.js | 1 - .../dir-a-wrapper/dir-a/dir-a-wrapper-3.js | 5 + .../dir-a-wrapper/dir-a/dir-a-wrapper-4.js | 5 + .../resolve-dir/dir-a/dir-a-base-1.js | 5 + .../resolve-dir/dir-a/dir-a-base-2.js | 5 + .../fixture/pkg-conf/resolve-dir/package.json | 7 + test/fork.js | 1 + test/hooks.js | 1 + test/profile.js | 4 +- test/reporters/mini.js | 5 +- test/reporters/verbose.js | 5 +- test/runner.js | 30 +- test/sequence.js | 352 +++++++++++++---- test/test-collection.js | 45 ++- test/test.js | 42 ++- test/visual/print-lorem-ipsum.js | 2 +- test/visual/run-visual-tests.js | 1 + test/watcher.js | 136 +++++-- 55 files changed, 1231 insertions(+), 897 deletions(-) delete mode 100644 lib/ava-files.js create mode 100644 lib/babel-config.js delete mode 100644 test/ava-files.js create mode 100644 test/babel-config.js delete mode 100644 test/fixture/ava-files/default-patterns/sub/directory/__tests__/_foo.js delete mode 100644 test/fixture/ava-files/default-patterns/sub/directory/__tests__/fixtures/foo.js delete mode 100644 test/fixture/ava-files/default-patterns/sub/directory/__tests__/foo.js delete mode 100644 test/fixture/ava-files/default-patterns/sub/directory/__tests__/helpers/foo.js delete mode 100644 test/fixture/ava-files/default-patterns/sub/directory/bar.test.js delete mode 100644 test/fixture/ava-files/default-patterns/test-foo.js delete mode 100644 test/fixture/ava-files/default-patterns/test.js delete mode 100644 test/fixture/ava-files/default-patterns/test/_foo-help.js delete mode 100644 test/fixture/ava-files/default-patterns/test/baz.js delete mode 100644 test/fixture/ava-files/default-patterns/test/deep/deep.js delete mode 100644 test/fixture/ava-files/default-patterns/test/fixtures/foo-fixt.js delete mode 100644 test/fixture/ava-files/default-patterns/test/helpers/test.js delete mode 100644 test/fixture/ava-files/no-duplicates/lib/bar.js delete mode 100644 test/fixture/ava-files/no-duplicates/lib/foo.js create mode 100644 test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-3.js create mode 100644 test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-4.js create mode 100644 test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-1.js create mode 100644 test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-2.js create mode 100644 test/fixture/pkg-conf/resolve-dir/package.json diff --git a/api.js b/api.js index 2b20af905..0b1075136 100644 --- a/api.js +++ b/api.js @@ -10,10 +10,10 @@ var uniqueTempDir = require('unique-temp-dir'); var findCacheDir = require('find-cache-dir'); var debounce = require('lodash.debounce'); var ms = require('ms'); +var AvaFiles = require('ava-files'); var AvaError = require('./lib/ava-error'); var fork = require('./lib/fork'); var CachingPrecompiler = require('./lib/caching-precompiler'); -var AvaFiles = require('./lib/ava-files'); var RunStatus = require('./lib/run-status'); function Api(options) { @@ -23,8 +23,12 @@ function Api(options) { EventEmitter.call(this); - this.options = options || {}; - this.options.match = this.options.match || []; + this.options = objectAssign({ + cwd: process.cwd(), + resolveTestsFrom: process.cwd(), + match: [] + }, options); + this.options.require = (this.options.require || []).map(function (moduleId) { var ret = resolveCwd(moduleId); if (ret === null) { @@ -73,7 +77,7 @@ Api.prototype._onTimeout = function (runStatus) { Api.prototype.run = function (files, options) { var self = this; - return new AvaFiles(files) + return new AvaFiles({files: files, cwd: this.options.resolveTestsFrom}) .findTestFiles() .then(function (files) { return self._run(files, options); @@ -109,8 +113,10 @@ Api.prototype._run = function (files, _options) { } var cacheEnabled = self.options.cacheEnabled !== false; - var cacheDir = (cacheEnabled && findCacheDir({name: 'ava', files: files})) || - uniqueTempDir(); + var cacheDir = (cacheEnabled && findCacheDir({ + name: 'ava', + files: files + })) || uniqueTempDir(); self.options.cacheDir = cacheDir; self.precompiler = new CachingPrecompiler(cacheDir, self.options.babelConfig); diff --git a/bench/run.js b/bench/run.js index 3cf15f7ef..32484045f 100644 --- a/bench/run.js +++ b/bench/run.js @@ -1,5 +1,4 @@ 'use strict'; - var childProcess = require('child_process'); var path = require('path'); var fs = require('fs'); @@ -7,6 +6,7 @@ var arrify = require('arrify'); var Promise = require('bluebird'); var mkdirp = require('mkdirp'); var branch = require('git-branch').sync(path.join(__dirname, '..')); + var cliPath = require.resolve('../cli'); function runTests(_args) { @@ -34,7 +34,10 @@ var list; if (process.argv.length === 2) { list = [ - {args: 'other/failures.js', shouldFail: true}, + { + args: 'other/failures.js', + shouldFail: true + }, 'serial/alternating-sync-async.js', 'serial/async-immediate.js', 'serial/async-timeout.js', @@ -94,22 +97,32 @@ var results = {}; Promise.each(combined, function (definition) { var args = definition.args; + return runTests(args).then(function (result) { var key = result.args.join(' '); var passedOrFaild = result.err ? 'failed' : 'passed'; var seconds = result.time / 1000; + console.log('%s %s in %d seconds', key, passedOrFaild, seconds); + if (result.err && !definition.shouldFail) { console.log(result.stdout); console.log(result.stderr); throw result.err; } + results[key] = results[key] || []; - results[key].push({passed: !results.err, shouldFail: definition.shouldFail, time: seconds}); + + results[key].push({ + passed: !results.err, + shouldFail: definition.shouldFail, + time: seconds + }); }); }).then(function () { mkdirp.sync(path.join(__dirname, '.results')); results['.time'] = Date.now(); + fs.writeFileSync( path.join(__dirname, '.results', branch + '.json'), JSON.stringify(results, null, 4) diff --git a/cli.js b/cli.js index d4b313c21..94cb33ab8 100755 --- a/cli.js +++ b/cli.js @@ -1,6 +1,7 @@ #!/usr/bin/env node 'use strict'; +var path = require('path'); var debug = require('debug')('ava'); // Prefer the local installation of AVA. @@ -23,7 +24,6 @@ var arrify = require('arrify'); var meow = require('meow'); var Promise = require('bluebird'); var pkgConf = require('pkg-conf'); -var chalk = require('chalk'); var isCi = require('is-ci'); var hasFlag = require('has-flag'); var colors = require('./lib/colors'); @@ -32,26 +32,20 @@ var miniReporter = require('./lib/reporters/mini'); var tapReporter = require('./lib/reporters/tap'); var Logger = require('./lib/logger'); var Watcher = require('./lib/watcher'); +var babelConfig = require('./lib/babel-config'); var Api = require('./api'); // Bluebird specific Promise.longStackTraces(); -var conf = pkgConf.sync('ava', { - defaults: { - babel: 'default' - } -}); - -// check for valid babel config shortcuts (can be either "default" or "inherit") -var isValidShortcut = ['default', 'inherit'].indexOf(conf.babel) !== -1; +var conf = pkgConf.sync('ava'); -if (!conf.babel || (typeof conf.babel === 'string' && !isValidShortcut)) { - var message = ''; - message += 'Unexpected Babel configuration for AVA. '; - message += 'See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.'; +var pkgDir = path.dirname(pkgConf.filepath(conf)); - console.log('\n ' + colors.error(figures.cross) + ' ' + message); +try { + conf.babel = babelConfig.validate(conf.babel); +} catch (err) { + console.log('\n ' + err.message); process.exit(1); } @@ -121,8 +115,8 @@ if (cli.flags.init) { } if ( - (hasFlag('--watch') || hasFlag('-w')) && (hasFlag('--tap') || hasFlag('-t')) || - conf.watch && conf.tap + ((hasFlag('--watch') || hasFlag('-w')) && (hasFlag('--tap') || hasFlag('-t'))) || + (conf.watch && conf.tap) ) { console.error(' ' + colors.error(figures.cross) + ' The TAP reporter is not available when using watch mode.'); process.exit(1); @@ -136,6 +130,7 @@ var api = new Api({ explicitTitles: cli.flags.watch, match: arrify(cli.flags.match), babelConfig: conf.babel, + resolveTestsFrom: cli.input.length === 0 ? pkgDir : process.cwd(), timeout: cli.flags.timeout, concurrency: cli.flags.concurrency ? parseInt(cli.flags.concurrency, 10) : 0 }); diff --git a/docs/recipes/react.md b/docs/recipes/react.md index 235a89ed6..d496631c1 100644 --- a/docs/recipes/react.md +++ b/docs/recipes/react.md @@ -9,7 +9,8 @@ The first step is setting up Babel to transpile JSX code from the tests by addin ```json { "ava": { - "require": ["babel-register"] + "require": ["babel-register"], + "babel": "inherit" }, "babel": { "presets": ["react"] diff --git a/docs/recipes/watch-mode.md b/docs/recipes/watch-mode.md index 20aae4c34..1fc2f1d0e 100644 --- a/docs/recipes/watch-mode.md +++ b/docs/recipes/watch-mode.md @@ -59,11 +59,7 @@ Please note that the TAP reporter is unavailable when using watch mode. ## Requirements -AVA uses [`chokidar`] as the file watcher. It's configured as an optional dependency since `chokidar` sometimes can't be installed. Watch mode is not available if `chokidar` fails to install, instead you'll see a message like: - -> The optional dependency chokidar failed to install and is required for --watch. Chokidar is likely not supported on your platform. - -Please refer to the [`chokidar` documentation][`chokidar`] for how to resolve this problem. +AVA uses [`chokidar`] as the file watcher. Note that even if you see warnings about optional dependencies failing during install, it will still work fine. Please refer to the *[Install Troubleshooting]* section of `chokidar` documentation for how to resolve the installation problems with chokidar. ## Source files and test files @@ -111,6 +107,7 @@ $ npm test -- --watch --verbose Watch mode is relatively new and there might be some rough edges. Please [report](https://github.com/avajs/ava/issues) any issues you encounter. Thanks! [`chokidar`]: https://github.com/paulmillr/chokidar +[Install Troubleshooting]: https://github.com/paulmillr/chokidar#install-troubleshooting [`ignore-by-default`]: https://github.com/novemberborn/ignore-by-default [`--require` CLI flag]: https://github.com/avajs/ava#cli [`--source` CLI flag]: https://github.com/avajs/ava#cli diff --git a/index.js b/index.js index 548554f0d..450bf026f 100644 --- a/index.js +++ b/index.js @@ -22,7 +22,7 @@ if (!isForked) { console.log(); console.error('Test files must be run with the AVA CLI:\n\n ' + chalk.grey.dim('$') + ' ' + chalk.cyan('ava ' + fp) + '\n'); - process.exit(1); // eslint-disable-line + process.exit(1); // eslint-disable-line xo/no-process-exit } // note that test files have require('ava') diff --git a/lib/assert.js b/lib/assert.js index 19b7b86aa..1188533b5 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -5,6 +5,7 @@ var deepEqual = require('not-so-shallow'); var observableToPromise = require('observable-to-promise'); var isObservable = require('is-observable'); var isPromise = require('is-promise'); + var x = module.exports; Object.defineProperty(x, 'AssertionError', {value: assert.AssertionError}); @@ -101,9 +102,9 @@ x.throws = function (fn, err, msg) { assert.throws(function () { try { fn(); - } catch (error) { - result = error; - throw error; + } catch (err) { + result = err; + throw err; } }, err, msg); diff --git a/lib/ava-files.js b/lib/ava-files.js deleted file mode 100644 index ef4938942..000000000 --- a/lib/ava-files.js +++ /dev/null @@ -1,262 +0,0 @@ -var fs = require('fs'); -var path = require('path'); -var Promise = require('bluebird'); -var slash = require('slash'); -var globby = require('globby'); -var flatten = require('arr-flatten'); -var defaultIgnore = require('ignore-by-default').directories(); -var multimatch = require('multimatch'); - -function defaultExcludePatterns() { - return [ - '!**/node_modules/**', - '!**/fixtures/**', - '!**/helpers/**' - ]; -} - -function defaultIncludePatterns() { - return [ - 'test.js', - 'test-*.js', - 'test', - '**/__tests__', - '**/*.test.js' - ]; -} - -function AvaFiles(files, sources) { - if (!(this instanceof AvaFiles)) { - throw new TypeError('Class constructor AvaFiles cannot be invoked without \'new\''); - } - - if (!files || !files.length) { - files = defaultIncludePatterns(); - } - - this.excludePatterns = defaultExcludePatterns(); - - this.files = files; - this.sources = sources || []; -} - -AvaFiles.prototype.findTestFiles = function () { - return handlePaths(this.files, this.excludePatterns, { - cache: Object.create(null), - statCache: Object.create(null), - realpathCache: Object.create(null), - symlinks: Object.create(null) - }); -}; - -function getDefaultIgnorePatterns() { - return defaultIgnore.map(function (dir) { - return dir + '/**/*'; - }); -} - -// Used on paths before they're passed to multimatch to harmonize matching -// across platforms. -var matchable = process.platform === 'win32' ? slash : function (path) { - return path; -}; - -AvaFiles.prototype.makeSourceMatcher = function () { - var mixedPatterns = []; - var defaultIgnorePatterns = getDefaultIgnorePatterns(); - var overrideDefaultIgnorePatterns = []; - - var hasPositivePattern = false; - this.sources.forEach(function (pattern) { - mixedPatterns.push(pattern); - // TODO: why not just pattern[0] !== '!' - if (!hasPositivePattern && pattern[0] !== '!') { - hasPositivePattern = true; - } - - // Extract patterns that start with an ignored directory. These need to be - // rematched separately. - if (defaultIgnore.indexOf(pattern.split('/')[0]) >= 0) { - overrideDefaultIgnorePatterns.push(pattern); - } - }); - - // Same defaults as used for Chokidar. - if (!hasPositivePattern) { - mixedPatterns = ['package.json', '**/*.js'].concat(mixedPatterns); - } - - return function (path) { - path = matchable(path); - - // Ignore paths outside the current working directory. They can't be matched - // to a pattern. - if (/^\.\.\//.test(path)) { - return false; - } - - var isSource = multimatch(path, mixedPatterns).length === 1; - if (!isSource) { - return false; - } - - var isIgnored = multimatch(path, defaultIgnorePatterns).length === 1; - if (!isIgnored) { - return true; - } - - var isErroneouslyIgnored = multimatch(path, overrideDefaultIgnorePatterns).length === 1; - if (isErroneouslyIgnored) { - return true; - } - - return false; - }; -}; - -AvaFiles.prototype.makeTestMatcher = function () { - var excludePatterns = this.excludePatterns; - var initialPatterns = this.files.concat(excludePatterns); - - return function (filepath) { - // Like in api.js, tests must be .js files and not start with _ - if (path.extname(filepath) !== '.js' || path.basename(filepath)[0] === '_') { - return false; - } - - // Check if the entire path matches a pattern. - if (multimatch(matchable(filepath), initialPatterns).length === 1) { - return true; - } - - // Check if the path contains any directory components. - var dirname = path.dirname(filepath); - if (dirname === '.') { - return false; - } - - // Compute all possible subpaths. Note that the dirname is assumed to be - // relative to the working directory, without a leading `./`. - var subpaths = dirname.split(/[\\\/]/).reduce(function (subpaths, component) { - var parent = subpaths[subpaths.length - 1]; - if (parent) { - // Always use / to makes multimatch consistent across platforms. - subpaths.push(parent + '/' + component); - } else { - subpaths.push(component); - } - return subpaths; - }, []); - - // Check if any of the possible subpaths match a pattern. If so, generate a - // new pattern with **/*.js. - var recursivePatterns = subpaths.filter(function (subpath) { - return multimatch(subpath, initialPatterns).length === 1; - }).map(function (subpath) { - // Always use / to makes multimatch consistent across platforms. - return subpath + '/**/*.js'; - }); - - // See if the entire path matches any of the subpaths patterns, taking the - // excludePatterns into account. This mimicks the behavior in api.js - return multimatch(matchable(filepath), recursivePatterns.concat(excludePatterns)).length === 1; - }; -}; - -AvaFiles.prototype.getChokidarPatterns = function () { - var paths = []; - var ignored = []; - - this.sources.forEach(function (pattern) { - if (pattern[0] === '!') { - ignored.push(pattern.slice(1)); - } else { - paths.push(pattern); - } - }); - - // Allow source patterns to override the default ignore patterns. Chokidar - // ignores paths that match the list of ignored patterns. It uses anymatch - // under the hood, which supports negation patterns. For any source pattern - // that starts with an ignored directory, ensure the corresponding negation - // pattern is added to the ignored paths. - var overrideDefaultIgnorePatterns = paths.filter(function (pattern) { - return defaultIgnore.indexOf(pattern.split('/')[0]) >= 0; - }).map(function (pattern) { - return '!' + pattern; - }); - ignored = getDefaultIgnorePatterns().concat(ignored, overrideDefaultIgnorePatterns); - - if (paths.length === 0) { - paths = ['package.json', '**/*.js']; - } - paths = paths.concat(this.files); - - return { - paths: paths, - ignored: ignored - }; -}; - -function handlePaths(files, excludePatterns, globOptions) { - // convert pinkie-promise to Bluebird promise - files = Promise.resolve(globby(files.concat(excludePatterns), globOptions)); - - var searchedParents = Object.create(null); - var foundFiles = Object.create(null); - - function alreadySearchingParent(dir) { - if (searchedParents[dir]) { - return true; - } - - var parentDir = path.dirname(dir); - - if (parentDir === dir) { - // We have reached the root path. - return false; - } - - return alreadySearchingParent(parentDir); - } - - return files - .map(function (file) { - if (fs.statSync(file).isDirectory()) { - if (alreadySearchingParent(file)) { - return null; - } - - searchedParents[file] = true; - - var pattern = path.join(file, '**', '*.js'); - - if (process.platform === 'win32') { - // Always use / in patterns, harmonizing matching across platforms. - pattern = slash(pattern); - } - - return handlePaths([pattern], excludePatterns, globOptions); - } - - // globby returns slashes even on Windows. Normalize here so the file - // paths are consistently platform-accurate as tests are run. - return path.normalize(file); - }) - .then(flatten) - .filter(function (file) { - return file && path.extname(file) === '.js' && path.basename(file)[0] !== '_'; - }) - .map(function (file) { - return path.resolve(file); - }) - .filter(function (file) { - var alreadyFound = foundFiles[file]; - foundFiles[file] = true; - return !alreadyFound; - }); -} - -module.exports = AvaFiles; -module.exports.defaultIncludePatterns = defaultIncludePatterns; -module.exports.defaultExcludePatterns = defaultExcludePatterns; diff --git a/lib/babel-config.js b/lib/babel-config.js new file mode 100644 index 000000000..0f3a138a0 --- /dev/null +++ b/lib/babel-config.js @@ -0,0 +1,146 @@ +'use strict'; +var path = require('path'); +var chalk = require('chalk'); +var figures = require('figures'); +var convertSourceMap = require('convert-source-map'); +var objectAssign = require('object-assign'); +var colors = require('./colors'); + +function validate(conf) { + if (conf === undefined || conf === null) { + conf = 'default'; + } + + // check for valid babel config shortcuts (can be either "default" or "inherit") + var isValidShortcut = conf === 'default' || conf === 'inherit'; + + if (!conf || (typeof conf === 'string' && !isValidShortcut)) { + var message = colors.error(figures.cross); + message += ' Unexpected Babel configuration for AVA. '; + message += 'See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.'; + + throw new Error(message); + } + + return conf; +} + +function lazy(initFn) { + var initialized = false; + var value; + + return function () { + if (!initialized) { + initialized = true; + value = initFn(); + } + + return value; + }; +} + +var defaultPresets = lazy(function () { + return [ + require('babel-preset-stage-2'), + require('babel-preset-es2015') + ]; +}); + +var rewritePlugin = lazy(function () { + var wrapListener = require('babel-plugin-detective/wrap-listener'); + + return wrapListener(rewriteBabelRuntimePaths, 'rewrite-runtime', { + generated: true, + require: true, + import: true + }); +}); + +function rewriteBabelRuntimePaths(path) { + var isBabelPath = /^babel-runtime[\\\/]?/.test(path.node.value); + + if (path.isLiteral() && isBabelPath) { + path.node.value = require.resolve(path.node.value); + } +} + +var espowerPlugin = lazy(function () { + var babel = require('babel-core'); + var createEspowerPlugin = require('babel-plugin-espower/create'); + + // initialize power-assert + return createEspowerPlugin(babel, { + embedAst: true, + patterns: require('./enhance-assert').PATTERNS + }); +}); + +var defaultPlugins = lazy(function () { + return [ + espowerPlugin(), + require('babel-plugin-ava-throws-helper'), + rewritePlugin(), + require('babel-plugin-transform-runtime') + ]; +}); + +function build(babelConfig, filePath, code) { + babelConfig = validate(babelConfig); + + var options; + + if (babelConfig === 'default') { + options = { + babelrc: false, + presets: defaultPresets() + }; + } else if (babelConfig === 'inherit') { + options = { + babelrc: true + }; + } else { + options = { + babelrc: false + }; + + objectAssign(options, babelConfig); + } + + var sourceMap = getSourceMap(filePath, code); + + objectAssign(options, { + inputSourceMap: sourceMap, + filename: filePath, + sourceMaps: true, + ast: false + }); + + options.plugins = (options.plugins || []).concat(defaultPlugins()); + + return options; +} + +function getSourceMap(filePath, code) { + var sourceMap = convertSourceMap.fromSource(code); + + if (!sourceMap) { + var dirPath = path.dirname(filePath); + + sourceMap = convertSourceMap.fromMapFileSource(code, dirPath); + } + + if (sourceMap) { + sourceMap = sourceMap.toObject(); + } + + return sourceMap; +} + +module.exports = { + validate: validate, + build: build, + pluginPackages: [ + require.resolve('babel-core/package.json'), + require.resolve('babel-plugin-espower/package.json') + ] +}; diff --git a/lib/caching-precompiler.js b/lib/caching-precompiler.js index da6d11375..fd26edc1d 100644 --- a/lib/caching-precompiler.js +++ b/lib/caching-precompiler.js @@ -3,18 +3,17 @@ var path = require('path'); var fs = require('fs'); var convertSourceMap = require('convert-source-map'); var cachingTransform = require('caching-transform'); -var objectAssign = require('object-assign'); var stripBom = require('strip-bom'); var md5Hex = require('md5-hex'); var packageHash = require('package-hash'); -var enhanceAssert = require('./enhance-assert'); +var babelConfigHelper = require('./babel-config'); function CachingPrecompiler(cacheDirPath, babelConfig) { if (!(this instanceof CachingPrecompiler)) { throw new TypeError('Class constructor CachingPrecompiler cannot be invoked without \'new\''); } - this.babelConfig = babelConfig || 'default'; + this.babelConfig = babelConfigHelper.validate(babelConfig); this.cacheDirPath = cacheDirPath; this.fileHashes = {}; @@ -46,29 +45,12 @@ CachingPrecompiler.prototype._factory = function () { CachingPrecompiler.prototype._init = function () { this.babel = require('babel-core'); - - this.defaultPresets = [ - require('babel-preset-stage-2'), - require('babel-preset-es2015') - ]; - - var transformRuntime = require('babel-plugin-transform-runtime'); - var throwsHelper = require('babel-plugin-ava-throws-helper'); - var rewriteBabelPaths = this._createRewritePlugin(); - var powerAssert = this._createEspowerPlugin(); - - this.defaultPlugins = [ - powerAssert, - throwsHelper, - rewriteBabelPaths, - transformRuntime - ]; }; CachingPrecompiler.prototype._transform = function (code, filePath, hash) { code = code.toString(); - var options = this._buildOptions(filePath, code); + var options = babelConfigHelper.build(this.babelConfig, filePath, code); var result = this.babel.transform(code, options); // save source map @@ -91,81 +73,11 @@ CachingPrecompiler.prototype._transform = function (code, filePath, hash) { return result.code + '\n' + comment; }; -CachingPrecompiler.prototype._buildOptions = function (filePath, code) { - var options = {babelrc: false}; - - if (this.babelConfig === 'default') { - objectAssign(options, {presets: this.defaultPresets}); - } else if (this.babelConfig === 'inherit') { - objectAssign(options, {babelrc: true}); - } else { - objectAssign(options, this.babelConfig); - } - - var sourceMap = this._getSourceMap(filePath, code); - - objectAssign(options, { - inputSourceMap: sourceMap, - filename: filePath, - sourceMaps: true, - ast: false - }); - - options.plugins = (options.plugins || []).concat(this.defaultPlugins); - - return options; -}; - -CachingPrecompiler.prototype._getSourceMap = function (filePath, code) { - var sourceMap = convertSourceMap.fromSource(code); - - if (!sourceMap) { - var dirPath = path.dirname(filePath); - - sourceMap = convertSourceMap.fromMapFileSource(code, dirPath); - } - - if (sourceMap) { - sourceMap = sourceMap.toObject(); - } - - return sourceMap; -}; - -CachingPrecompiler.prototype._createRewritePlugin = function () { - var wrapListener = require('babel-plugin-detective/wrap-listener'); - - return wrapListener(this._rewriteBabelRuntimePaths, 'rewrite-runtime', { - generated: true, - require: true, - import: true - }); -}; - -CachingPrecompiler.prototype._rewriteBabelRuntimePaths = function (path) { - var isBabelPath = /^babel-runtime[\\\/]?/.test(path.node.value); - - if (path.isLiteral() && isBabelPath) { - path.node.value = require.resolve(path.node.value); - } -}; - -CachingPrecompiler.prototype._createEspowerPlugin = function () { - var createEspowerPlugin = require('babel-plugin-espower/create'); - - // initialize power-assert - return createEspowerPlugin(this.babel, { - embedAst: true, - patterns: enhanceAssert.PATTERNS - }); -}; - CachingPrecompiler.prototype._createTransform = function () { - var salt = packageHash.sync([ - require.resolve('../package.json'), - require.resolve('babel-core/package.json'), - require.resolve('babel-plugin-espower/package.json') - ], JSON.stringify(this.babelConfig)); + var salt = packageHash.sync( + [require.resolve('../package.json')].concat(babelConfigHelper.pluginPackages), + JSON.stringify(this.babelConfig) + ); return cachingTransform({ factory: this._factory, diff --git a/lib/enhance-assert.js b/lib/enhance-assert.js index 86908b89e..a7f28cdfa 100644 --- a/lib/enhance-assert.js +++ b/lib/enhance-assert.js @@ -31,6 +31,7 @@ module.exports.NON_ENHANCED_PATTERNS = [ function enhanceAssert(opts) { var empower = require('empower-core'); + var enhanced = empower( opts.assert, { @@ -53,8 +54,15 @@ function formatter() { return createFormatter({ renderers: [ - {ctor: AssertionRenderer}, - {ctor: SuccinctRenderer, options: {maxDepth: 3}} + { + ctor: AssertionRenderer + }, + { + ctor: SuccinctRenderer, + options: { + maxDepth: 3 + } + } ] }); } diff --git a/lib/logger.js b/lib/logger.js index 3a389eb64..0d6ea7ea1 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -99,6 +99,6 @@ Logger.prototype.exit = function (code) { // timeout required to correctly flush IO on Node.js 0.10 on Windows setTimeout(function () { - process.exit(code); // eslint-disable-line + process.exit(code); // eslint-disable-line xo/no-process-exit }, process.env.AVA_APPVEYOR ? 500 : 0); }; diff --git a/lib/test-worker.js b/lib/test-worker.js index fe41bdaee..37abb70fc 100644 --- a/lib/test-worker.js +++ b/lib/test-worker.js @@ -38,7 +38,7 @@ if (debug.enabled) { // bind globals first before anything has a chance to interfere var globals = require('./globals'); globals.options = opts; -var Promise = require('bluebird'); // eslint-disable-line +var Promise = require('bluebird'); // eslint-disable-line import/order // Bluebird specific Promise.longStackTraces(); @@ -60,11 +60,11 @@ sourceMapSupport.install({ } }); -var currentlyUnhandled = require('currently-unhandled')(); // eslint-disable-line +var currentlyUnhandled = require('currently-unhandled')(); // eslint-disable-line import/order var serializeError = require('./serialize-error'); var send = require('./send'); var throwsHelper = require('./throws-helper'); -var installPrecompiler = require('require-precompiled'); // eslint-disable-line +var installPrecompiler = require('require-precompiled'); // eslint-disable-line import/order var cacheDir = opts.cacheDir; // check if test files required ava and show error, when they didn't @@ -120,7 +120,7 @@ process.on('ava-exit', function () { var delay = process.env.AVA_APPVEYOR ? 100 : 0; globals.setTimeout(function () { - process.exit(0); // eslint-disable-line + process.exit(0); // eslint-disable-line xo/no-process-exit }, delay); }); diff --git a/lib/test.js b/lib/test.js index 777b33b0e..5a76e1364 100644 --- a/lib/test.js +++ b/lib/test.js @@ -118,7 +118,7 @@ Test.prototype.promise = function () { if (!this._promise) { this._promise = {}; - this._promise.promise = new Promise(function (resolve, reject) { // eslint-disable-line + this._promise.promise = new Promise(function (resolve, reject) { // eslint-disable-line no-use-extend-native/no-use-extend-native self._promise.resolve = resolve; self._promise.reject = reject; }).tap(function (result) { @@ -189,15 +189,22 @@ Test.prototype.run = function () { Test.prototype._result = function () { var reason = this.assertError; var passed = reason === undefined; + if (this.metadata.failing) { passed = !passed; + if (passed) { reason = undefined; } else { reason = new Error('Test was expected to fail, but succeeded, you should stop marking the test as failing'); } } - return {passed: passed, result: this, reason: reason}; + + return { + passed: passed, + result: this, + reason: reason + }; }; Object.defineProperty(Test.prototype, 'end', { @@ -219,9 +226,10 @@ Test.prototype._end = function (err) { operator: 'callback' }); } - this._setAssertError(err); + this._setAssertError(err); this.exit(); + return; } diff --git a/lib/throws-helper.js b/lib/throws-helper.js index 405cefc64..c8ff5e527 100644 --- a/lib/throws-helper.js +++ b/lib/throws-helper.js @@ -16,8 +16,8 @@ module.exports = function throwsHelper(error) { try { var rawLines = fs.readFileSync(data.filename, 'utf8'); frame = codeFrame(rawLines, data.line, data.column, {highlightCode: true}); - } catch (e) { - console.warn(e); + } catch (err) { + console.warn(err); } console.error( diff --git a/lib/watcher.js b/lib/watcher.js index 5203e9fe2..85382bef4 100644 --- a/lib/watcher.js +++ b/lib/watcher.js @@ -2,19 +2,11 @@ var nodePath = require('path'); var debug = require('debug')('ava:watcher'); var diff = require('lodash.difference'); +var chokidar = require('chokidar'); var flatten = require('arr-flatten'); var union = require('array-union'); var uniq = require('array-uniq'); -var AvaError = require('./ava-error'); -var AvaFiles = require('./ava-files'); - -function requireChokidar() { - try { - return require('chokidar'); - } catch (err) { - throw new AvaError('The optional dependency chokidar failed to install and is required for --watch. Chokidar is likely not supported on your platform.'); - } -} +var AvaFiles = require('ava-files'); function rethrowAsync(err) { // Don't swallow exceptions. Note that any expected error should already have @@ -26,7 +18,10 @@ function rethrowAsync(err) { function Watcher(logger, api, files, sources) { this.debouncer = new Debouncer(this); - this.avaFiles = new AvaFiles(files, sources); + this.avaFiles = new AvaFiles({ + files: files, + sources: sources + }); this.isTest = this.avaFiles.makeTestMatcher(); @@ -96,7 +91,7 @@ Watcher.prototype.watchFiles = function () { var self = this; var patterns = this.avaFiles.getChokidarPatterns(); - requireChokidar().watch(patterns.paths, { + chokidar.watch(patterns.paths, { ignored: patterns.ignored, ignoreInitial: true }).on('all', function (event, path) { diff --git a/package.json b/package.json index 3c16f93e5..2acc191bc 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "array-union": "^1.0.1", "array-uniq": "^1.0.2", "arrify": "^1.0.0", + "ava-files": "^0.1.1", "ava-init": "^0.1.0", "babel-code-frame": "^6.7.5", "babel-core": "^6.3.21", @@ -94,6 +95,7 @@ "bluebird": "^3.0.0", "caching-transform": "^1.0.0", "chalk": "^1.0.0", + "chokidar": "^1.4.2", "clean-yaml-object": "^0.1.0", "cli-cursor": "^1.0.2", "cli-spinners": "^0.1.2", @@ -108,7 +110,7 @@ "figures": "^1.4.0", "find-cache-dir": "^0.1.1", "fn-name": "^2.0.0", - "globby": "^4.0.0", + "globby": "^5.0.0", "has-flag": "^2.0.0", "ignore-by-default": "^1.0.0", "is-ci": "^1.0.7", @@ -148,7 +150,7 @@ "strip-bom": "^2.0.0", "time-require": "^0.1.2", "unique-temp-dir": "^1.0.0", - "update-notifier": "^0.7.0" + "update-notifier": "^1.0.0" }, "devDependencies": { "babel-preset-react": "^6.5.0", @@ -166,7 +168,7 @@ "pify": "^2.3.0", "proxyquire": "^1.7.4", "rimraf": "^2.5.0", - "signal-exit": "^2.1.2", + "signal-exit": "^3.0.0", "sinon": "^1.17.2", "source-map-fixtures": "^2.1.0", "tap": "^5.4.2", @@ -174,7 +176,17 @@ "xo": "*", "zen-observable": "^0.2.1" }, - "optionalDependencies": { - "chokidar": "^1.4.2" + "xo": { + "rules": { + "import/newline-after-import": 0 + }, + "overrides": [ + { + "files": ["test/**/*.js"], + "rules": { + "max-lines": 0 + } + } + ] } } diff --git a/profile.js b/profile.js index 15215d339..0cb78b760 100644 --- a/profile.js +++ b/profile.js @@ -60,7 +60,10 @@ if (cli.input.length !== 1) { } var file = path.resolve(cli.input[0]); -var cacheDir = findCacheDir({name: 'ava', files: [file]}) || uniqueTempDir(); +var cacheDir = findCacheDir({ + name: 'ava', + files: [file] +}) || uniqueTempDir(); var precompiled = {}; precompiled[file] = new CachingPrecompiler(cacheDir, conf.babel).precompileFile(file); @@ -107,7 +110,7 @@ events.on('results', function (data) { if (process.exit) { // Delay is For Node 0.10 which emits uncaughtExceptions async. setTimeout(function () { - process.exit(data.stats.failCount + uncaughtExceptionCount); // eslint-disable-line + process.exit(data.stats.failCount + uncaughtExceptionCount); // eslint-disable-line xo/no-process-exit }, 20); } }); diff --git a/test/assert.js b/test/assert.js index 574964ed4..c0452b166 100644 --- a/test/assert.js +++ b/test/assert.js @@ -128,11 +128,29 @@ test('.deepEqual()', function (t) { }); t.doesNotThrow(function () { - assert.deepEqual({a: 'a', b: 'b'}, {b: 'b', a: 'a'}); + assert.deepEqual({ + a: 'a', + b: 'b' + }, { + b: 'b', + a: 'a' + }); }); t.doesNotThrow(function () { - assert.deepEqual({a: 'a', b: 'b', c: {d: 'd'}}, {c: {d: 'd'}, b: 'b', a: 'a'}); + assert.deepEqual({ + a: 'a', + b: 'b', + c: { + d: 'd' + } + }, { + c: { + d: 'd' + }, + b: 'b', + a: 'a' + }); }); t.throws(function () { @@ -197,7 +215,19 @@ test('.deepEqual()', function (t) { }); t.throws(function () { - assert.deepEqual({a: 'a', b: 'b', c: {d: false}}, {c: {d: 0}, b: 'b', a: 'a'}); + assert.deepEqual({ + a: 'a', + b: 'b', + c: { + d: false + } + }, { + c: { + d: 0 + }, + b: 'b', + a: 'a' + }); }); // Regression test end here @@ -290,7 +320,10 @@ test('.throws should throw if passed a bad value', function (t) { t.throws(function () { assert.throws('not a function'); - }, {name: 'TypeError', message: /t\.throws must be called with a function, Promise, or Observable/}); + }, { + name: 'TypeError', + message: /t\.throws must be called with a function, Promise, or Observable/ + }); }); test('.notThrows should throw if passed a bad value', function (t) { @@ -298,7 +331,10 @@ test('.notThrows should throw if passed a bad value', function (t) { t.throws(function () { assert.notThrows('not a function'); - }, {name: 'TypeError', message: /t\.notThrows must be called with a function, Promise, or Observable/}); + }, { + name: 'TypeError', + message: /t\.notThrows must be called with a function, Promise, or Observable/ + }); }); test('.notThrows()', function (t) { diff --git a/test/ava-files.js b/test/ava-files.js deleted file mode 100644 index 4426b769c..000000000 --- a/test/ava-files.js +++ /dev/null @@ -1,143 +0,0 @@ -'use strict'; -var path = require('path'); -var tap = require('tap'); -var test = tap.test; -var AvaFiles = require('../lib/ava-files'); - -tap.afterEach(function (done) { - // We changed the CWD in some of the tests. - process.chdir(path.join(__dirname, '..')); - done(); -}); - -function fixture() { - var args = Array.prototype.slice.call(arguments); - args.unshift(__dirname, 'fixture', 'ava-files'); - return path.join.apply(path, args); -} - -test('requires new', function (t) { - var avaFiles = AvaFiles; - t.throws(function () { - avaFiles(['**/foo*']); - }, 'Class constructor AvaFiles cannot be invoked without \'new\''); - t.end(); -}); - -test('testMatcher', function (t) { - var avaFiles = new AvaFiles(['**/foo*']); - - var matcher = avaFiles.makeTestMatcher(); - - function isTest(file) { - t.true(matcher(file), file + ' should be a test'); - } - - function notTest(file) { - t.false(matcher(file), file + ' should not be a test'); - } - - isTest('foo-bar.js'); - isTest('foo.js'); - isTest('foo/blah.js'); - isTest('bar/foo.js'); - isTest('bar/foo-bar/baz/buz.js'); - notTest('bar/baz/buz.js'); - notTest('bar.js'); - notTest('bar/bar.js'); - notTest('_foo-bar.js'); - notTest('foo/_foo-bar.js'); - notTest('foo-bar.txt'); - notTest('node_modules/foo.js'); - notTest('fixtures/foo.js'); - notTest('helpers/foo.js'); - t.end(); -}); - -test('sourceMatcher - defaults', function (t) { - var avaFiles = new AvaFiles(['**/foo*']); - - var matcher = avaFiles.makeSourceMatcher(); - - function isSource(file) { - t.true(matcher(file), file + ' should be a source'); - } - - function notSource(file) { - t.false(matcher(file), file + ' should not be a source'); - } - - isSource('foo-bar.js'); - isSource('foo.js'); - isSource('foo/blah.js'); - isSource('bar/foo.js'); - - isSource('_foo-bar.js'); - isSource('foo/_foo-bar.js'); - isSource('fixtures/foo.js'); - isSource('helpers/foo.js'); - - // TODO: Watcher should probably track any required file that matches the source pattern and has a require extension installed for the given extension. - notSource('foo-bar.json'); - notSource('foo-bar.coffee'); - - // These seem OK - isSource('bar.js'); - isSource('bar/bar.js'); - notSource('node_modules/foo.js'); - - t.end(); -}); - -test('sourceMatcher - allow matching specific node_modules directories', function (t) { - var avaFiles = new AvaFiles(['**/foo*'], ['node_modules/foo/**']); - - var matcher = avaFiles.makeSourceMatcher(); - - t.true(matcher('node_modules/foo/foo.js')); - t.false(matcher('node_modules/bar/foo.js')); - t.end(); -}); - -test('sourceMatcher - providing negation patterns', function (t) { - var avaFiles = new AvaFiles(['**/foo*'], ['!**/bar*']); - - var matcher = avaFiles.makeSourceMatcher(); - - t.false(matcher('node_modules/foo/foo.js')); - t.false(matcher('bar.js')); - t.false(matcher('foo/bar.js')); - t.end(); -}); - -test('findFiles - does not return duplicates of the same file', function (t) { - var avaFiles = new AvaFiles(['**/ava-files/no-duplicates/**']); - - avaFiles.findTestFiles().then(function (files) { - t.is(files.length, 2); - t.end(); - }); -}); - -test('findFiles - finds the correct files by default', function (t) { - var fixtureDir = fixture('default-patterns'); - process.chdir(fixtureDir); - - var expected = [ - 'sub/directory/__tests__/foo.js', - 'sub/directory/bar.test.js', - 'test-foo.js', - 'test.js', - 'test/baz.js', - 'test/deep/deep.js' - ].map(function (file) { - return path.join(fixtureDir, file); - }).sort(); - - var avaFiles = new AvaFiles(); - avaFiles.findTestFiles().then(function (files) { - files.sort(); - t.deepEqual(files, expected); - t.end(); - }); -}); diff --git a/test/babel-config.js b/test/babel-config.js new file mode 100644 index 000000000..1e9d86a60 --- /dev/null +++ b/test/babel-config.js @@ -0,0 +1,50 @@ +'use strict'; +var fs = require('fs'); +var path = require('path'); +var test = require('tap').test; +var sinon = require('sinon'); +var proxyquire = require('proxyquire').noCallThru(); +var throwsHelper = require('babel-plugin-ava-throws-helper'); +var transformRuntime = require('babel-plugin-transform-runtime'); + +function fixture(name) { + return path.join(__dirname, 'fixture', name); +} + +test('uses babelConfig for babel options when babelConfig is an object', function (t) { + var customPlugin = sinon.stub().returns({visitor: {}}); + var powerAssert = sinon.stub().returns({visitor: {}}); + var rewrite = sinon.stub().returns({visitor: {}}); + + function createEspowerPlugin() { + return powerAssert; + } + + function babelDetectiveWrap() { + return rewrite; + } + + var babelConfigHelper = proxyquire('../lib/babel-config', { + 'babel-plugin-espower/create': createEspowerPlugin, + 'babel-plugin-detective/wrap-listener': babelDetectiveWrap + }); + + var babelConfig = { + presets: ['stage-2', 'es2015'], + plugins: [customPlugin] + }; + + var fixturePath = fixture('es2015.js'); + var fixtureSource = fs.readFileSync(fixturePath, 'utf8'); + + var options = babelConfigHelper.build(babelConfig, fixturePath, fixtureSource); + + t.true('filename' in options); + t.true(options.sourceMaps); + t.false(options.ast); + t.true('inputSourceMap' in options); + t.false(options.babelrc); + t.strictDeepEqual(options.presets, ['stage-2', 'es2015']); + t.strictDeepEqual(options.plugins, [customPlugin, powerAssert, throwsHelper, rewrite, transformRuntime]); + t.end(); +}); diff --git a/test/caching-precompiler.js b/test/caching-precompiler.js index c63c443f2..502e3d320 100644 --- a/test/caching-precompiler.js +++ b/test/caching-precompiler.js @@ -5,8 +5,6 @@ var test = require('tap').test; var uniqueTempDir = require('unique-temp-dir'); var sinon = require('sinon'); var babel = require('babel-core'); -var transformRuntime = require('babel-plugin-transform-runtime'); -var throwsHelper = require('babel-plugin-ava-throws-helper'); var fromMapFileSource = require('convert-source-map').fromMapFileSource; var CachingPrecompiler = require('../lib/caching-precompiler'); @@ -122,34 +120,6 @@ test('allows babel config from package.json/babel when babelConfig === "inherit" t.end(); }); -test('uses babelConfig for babel options when babelConfig is an object', function (t) { - var tempDir = uniqueTempDir(); - var customPlugin = sinon.stub().returns({visitor: {}}); - var powerAssert = sinon.stub().returns({visitor: {}}); - var rewrite = sinon.stub().returns({visitor: {}}); - var precompiler = new CachingPrecompiler(tempDir, { - presets: ['stage-2', 'es2015'], - plugins: [customPlugin] - }); - sinon.stub(precompiler, '_createEspowerPlugin').returns(powerAssert); - sinon.stub(precompiler, '_createRewritePlugin').returns(rewrite); - babel.transform.reset(); - - precompiler.precompileFile(fixture('es2015.js')); - - t.true(babel.transform.calledOnce); - var options = babel.transform.firstCall.args[1]; - - t.true('filename' in options); - t.true(options.sourceMaps); - t.false(options.ast); - t.true('inputSourceMap' in options); - t.false(options.babelrc); - t.strictDeepEqual(options.presets, ['stage-2', 'es2015']); - t.strictDeepEqual(options.plugins, [customPlugin, powerAssert, throwsHelper, rewrite, transformRuntime]); - t.end(); -}); - test('does not modify plugins array in babelConfig', function (t) { var plugins = []; var precompiler = new CachingPrecompiler(uniqueTempDir(), { diff --git a/test/cli.js b/test/cli.js index 907f1bbc3..dc7f54c15 100644 --- a/test/cli.js +++ b/test/cli.js @@ -8,18 +8,13 @@ var figures = require('figures'); var arrify = require('arrify'); var chalk = require('chalk'); var touch = require('touch'); + var cliPath = path.join(__dirname, '../cli.js'); // for some reason chalk is disabled by default chalk.enabled = true; var colors = require('../lib/colors'); -var hasChokidar = false; -try { - require('chokidar'); - hasChokidar = true; -} catch (err) {} - function execCli(args, opts, cb) { var dirname; var env; @@ -176,19 +171,46 @@ test('pkg-conf: cli takes precedence', function (t) { }); }); +test('pkg-conf(resolve-dir): works as expected when run from the package.json directory', function (t) { + execCli(['--verbose'], {dirname: 'fixture/pkg-conf/resolve-dir'}, function (err, stdout, stderr) { + t.ifError(err); + t.match(stderr, /dir-a-base-1/); + t.match(stderr, /dir-a-base-2/); + t.notMatch(stderr, /dir-a-wrapper/); + t.notMatch(stdout, /dir-a-wrapper/); + t.end(); + }); +}); + +test('pkg-conf(resolve-dir): resolves tests from the package.json dir if none are specified on cli', function (t) { + execCli(['--verbose'], {dirname: 'fixture/pkg-conf/resolve-dir/dir-a-wrapper'}, function (err, stdout, stderr) { + t.ifError(err); + t.match(stderr, /dir-a-base-1/); + t.match(stderr, /dir-a-base-2/); + t.notMatch(stderr, /dir-a-wrapper/); + t.notMatch(stdout, /dir-a-wrapper/); + t.end(); + }); +}); + +test('pkg-conf(resolve-dir): resolves tests process.cwd() if globs are passed on the command line', function (t) { + execCli(['--verbose', 'dir-a/*.js'], {dirname: 'fixture/pkg-conf/resolve-dir/dir-a-wrapper'}, function (err, stdout, stderr) { + t.ifError(err); + t.match(stderr, /dir-a-wrapper-3/); + t.match(stderr, /dir-a-wrapper-4/); + t.notMatch(stderr, /dir-a-base/); + t.notMatch(stdout, /dir-a-base/); + t.end(); + }); +}); + test('watcher reruns test files when they changed', function (t) { var killed = false; - var child = execCli(['--verbose', '--watch', 'test.js'], {dirname: 'fixture/watcher'}, function (err, stdout, stderr) { - if (err && err.code === 1 && !hasChokidar) { - t.comment('chokidar dependency is missing, cannot test watcher'); - t.match(stderr, 'The optional dependency chokidar failed to install and is required for --watch. Chokidar is likely not supported on your platform.'); - t.end(); - } else { - t.ok(killed); - t.ifError(err); - t.end(); - } + var child = execCli(['--verbose', '--watch', 'test.js'], {dirname: 'fixture/watcher'}, function (err) { + t.ok(killed); + t.ifError(err); + t.end(); }); var buffer = ''; @@ -208,72 +230,70 @@ test('watcher reruns test files when they changed', function (t) { }); }); -if (hasChokidar) { - test('watcher reruns test files when source dependencies change', function (t) { - var killed = false; - - var child = execCli(['--verbose', '--watch', '--source=source.js', 'test-*.js'], {dirname: 'fixture/watcher/with-dependencies'}, function (err) { - t.ok(killed); - t.ifError(err); - t.end(); - }); +test('watcher reruns test files when source dependencies change', function (t) { + var killed = false; - var buffer = ''; - var passedFirst = false; - child.stderr.on('data', function (str) { - buffer += str; - if (/2 tests passed/.test(buffer) && !passedFirst) { - touch.sync(path.join(__dirname, 'fixture/watcher/with-dependencies/source.js')); - buffer = ''; - passedFirst = true; - } else if (/1 test passed/.test(buffer) && !killed) { - child.kill(); - killed = true; - } - }); + var child = execCli(['--verbose', '--watch', '--source=source.js', 'test-*.js'], {dirname: 'fixture/watcher/with-dependencies'}, function (err) { + t.ok(killed); + t.ifError(err); + t.end(); }); - test('`"tap": true` config is ignored when --watch is given', function (t) { - var killed = false; + var buffer = ''; + var passedFirst = false; + child.stderr.on('data', function (str) { + buffer += str; + if (/2 tests passed/.test(buffer) && !passedFirst) { + touch.sync(path.join(__dirname, 'fixture/watcher/with-dependencies/source.js')); + buffer = ''; + passedFirst = true; + } else if (/1 test passed/.test(buffer) && !killed) { + child.kill(); + killed = true; + } + }); +}); - var child = execCli(['--watch', 'test.js'], {dirname: 'fixture/watcher/tap-in-conf'}, function () { - t.ok(killed); - t.end(); - }); +test('`"tap": true` config is ignored when --watch is given', function (t) { + var killed = false; - var combined = ''; - var testOutput = function (output) { - combined += output; - t.notMatch(combined, /TAP/); - if (/works/.test(combined)) { - child.kill(); - killed = true; - } - }; - child.stdout.on('data', testOutput); - child.stderr.on('data', testOutput); + var child = execCli(['--watch', 'test.js'], {dirname: 'fixture/watcher/tap-in-conf'}, function () { + t.ok(killed); + t.end(); }); - test('bails when config contains `"tap": true` and `"watch": true`', function (t) { - execCli(['test.js'], {dirname: 'fixture/watcher/tap-and-watch-in-conf'}, function (err, stdout, stderr) { - t.is(err.code, 1); - t.match(stderr, 'The TAP reporter is not available when using watch mode.'); - t.end(); - }); + var combined = ''; + var testOutput = function (output) { + combined += output; + t.notMatch(combined, /TAP/); + if (/works/.test(combined)) { + child.kill(); + killed = true; + } + }; + child.stdout.on('data', testOutput); + child.stderr.on('data', testOutput); +}); + +test('bails when config contains `"tap": true` and `"watch": true`', function (t) { + execCli(['test.js'], {dirname: 'fixture/watcher/tap-and-watch-in-conf'}, function (err, stdout, stderr) { + t.is(err.code, 1); + t.match(stderr, 'The TAP reporter is not available when using watch mode.'); + t.end(); }); +}); - ['--watch', '-w'].forEach(function (watchFlag) { - ['--tap', '-t'].forEach(function (tapFlag) { - test('bails when ' + tapFlag + ' reporter is used while ' + watchFlag + ' is given', function (t) { - execCli([tapFlag, watchFlag, 'test.js'], {dirname: 'fixture/watcher'}, function (err, stdout, stderr) { - t.is(err.code, 1); - t.match(stderr, 'The TAP reporter is not available when using watch mode.'); - t.end(); - }); +['--watch', '-w'].forEach(function (watchFlag) { + ['--tap', '-t'].forEach(function (tapFlag) { + test('bails when ' + tapFlag + ' reporter is used while ' + watchFlag + ' is given', function (t) { + execCli([tapFlag, watchFlag, 'test.js'], {dirname: 'fixture/watcher'}, function (err, stdout, stderr) { + t.is(err.code, 1); + t.match(stderr, 'The TAP reporter is not available when using watch mode.'); + t.end(); }); }); }); -} +}); test('--match works', function (t) { execCli(['-m=foo', '-m=bar', '-m=!baz', '-m=t* a* f*', '-m=!t* a* n* f*', 'fixture/matcher-skip.js'], function (err) { diff --git a/test/concurrent.js b/test/concurrent.js index ada38c880..00a02ded3 100644 --- a/test/concurrent.js +++ b/test/concurrent.js @@ -69,9 +69,18 @@ test('all sync - all pass - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -91,9 +100,18 @@ test('all sync - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -113,9 +131,18 @@ test('all sync - begin failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -135,9 +162,18 @@ test('all sync - mid failure - no bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: false, + reason: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -157,9 +193,18 @@ test('all sync - end failure - no bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -179,9 +224,18 @@ test('all sync - multiple failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -201,7 +255,10 @@ test('all sync - begin failure - bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'} + { + passed: false, + reason: 'a' + } ] }); t.end(); @@ -221,8 +278,14 @@ test('all sync - mid failure - bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'} + { + passed: true, + result: 'a' + }, + { + passed: false, + reason: 'b' + } ] }); t.end(); @@ -242,9 +305,18 @@ test('all sync - end failure - bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -263,9 +335,18 @@ test('all async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -285,9 +366,18 @@ test('all async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -307,9 +397,18 @@ test('last async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -329,9 +428,18 @@ test('mid async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -351,9 +459,18 @@ test('first async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -373,9 +490,18 @@ test('last async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -395,9 +521,18 @@ test('mid async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -417,9 +552,18 @@ test('first async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -439,7 +583,10 @@ test('all async - begin failure - bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'} + { + passed: false, + reason: 'a' + } ] }); t.end(); @@ -459,8 +606,14 @@ test('all async - mid failure - bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'} + { + passed: true, + result: 'a' + }, + { + passed: false, + reason: 'b' + } ] }); t.end(); @@ -480,9 +633,18 @@ test('all async - end failure - bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -502,9 +664,18 @@ test('all async - begin failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -524,9 +695,18 @@ test('all async - mid failure - no bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: false, + reason: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -546,9 +726,18 @@ test('all async - end failure - no bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -568,9 +757,18 @@ test('all async - multiple failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -585,8 +783,8 @@ test('rejections are just passed through - no bail', function (t) { reject('foo') ], false - ).run().catch(function (reason) { - t.is(reason, 'foo'); + ).run().catch(function (err) { + t.is(err, 'foo'); t.end(); }); }); @@ -599,8 +797,8 @@ test('rejections are just passed through - bail', function (t) { reject('foo') ], true - ).run().catch(function (reason) { - t.is(reason, 'foo'); + ).run().catch(function (err) { + t.is(err, 'foo'); t.end(); }); }); @@ -627,15 +825,24 @@ test('sequences of sequences', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + } ] }, { passed: true, reason: null, result: [ - {passed: true, result: 'c'} + { + passed: true, + result: 'c' + } ] } ] diff --git a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/_foo.js b/test/fixture/ava-files/default-patterns/sub/directory/__tests__/_foo.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/_foo.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/fixtures/foo.js b/test/fixture/ava-files/default-patterns/sub/directory/__tests__/fixtures/foo.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/fixtures/foo.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/foo.js b/test/fixture/ava-files/default-patterns/sub/directory/__tests__/foo.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/foo.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/helpers/foo.js b/test/fixture/ava-files/default-patterns/sub/directory/__tests__/helpers/foo.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/sub/directory/__tests__/helpers/foo.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/sub/directory/bar.test.js b/test/fixture/ava-files/default-patterns/sub/directory/bar.test.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/sub/directory/bar.test.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/test-foo.js b/test/fixture/ava-files/default-patterns/test-foo.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/test-foo.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/test.js b/test/fixture/ava-files/default-patterns/test.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/test.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/test/_foo-help.js b/test/fixture/ava-files/default-patterns/test/_foo-help.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/test/_foo-help.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/test/baz.js b/test/fixture/ava-files/default-patterns/test/baz.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/test/baz.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/test/deep/deep.js b/test/fixture/ava-files/default-patterns/test/deep/deep.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/test/deep/deep.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/test/fixtures/foo-fixt.js b/test/fixture/ava-files/default-patterns/test/fixtures/foo-fixt.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/test/fixtures/foo-fixt.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/default-patterns/test/helpers/test.js b/test/fixture/ava-files/default-patterns/test/helpers/test.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/default-patterns/test/helpers/test.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/no-duplicates/lib/bar.js b/test/fixture/ava-files/no-duplicates/lib/bar.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/no-duplicates/lib/bar.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/ava-files/no-duplicates/lib/foo.js b/test/fixture/ava-files/no-duplicates/lib/foo.js deleted file mode 100644 index 8b1a39374..000000000 --- a/test/fixture/ava-files/no-duplicates/lib/foo.js +++ /dev/null @@ -1 +0,0 @@ -// empty diff --git a/test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-3.js b/test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-3.js new file mode 100644 index 000000000..f7f3994d5 --- /dev/null +++ b/test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-3.js @@ -0,0 +1,5 @@ +import test from '../../../../../../'; + +test(t => { + t.pass(); +}); diff --git a/test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-4.js b/test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-4.js new file mode 100644 index 000000000..f7f3994d5 --- /dev/null +++ b/test/fixture/pkg-conf/resolve-dir/dir-a-wrapper/dir-a/dir-a-wrapper-4.js @@ -0,0 +1,5 @@ +import test from '../../../../../../'; + +test(t => { + t.pass(); +}); diff --git a/test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-1.js b/test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-1.js new file mode 100644 index 000000000..f5af94d7a --- /dev/null +++ b/test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-1.js @@ -0,0 +1,5 @@ +import test from '../../../../../'; + +test(t => { + t.pass(); +}); diff --git a/test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-2.js b/test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-2.js new file mode 100644 index 000000000..f5af94d7a --- /dev/null +++ b/test/fixture/pkg-conf/resolve-dir/dir-a/dir-a-base-2.js @@ -0,0 +1,5 @@ +import test from '../../../../../'; + +test(t => { + t.pass(); +}); diff --git a/test/fixture/pkg-conf/resolve-dir/package.json b/test/fixture/pkg-conf/resolve-dir/package.json new file mode 100644 index 000000000..7634802f2 --- /dev/null +++ b/test/fixture/pkg-conf/resolve-dir/package.json @@ -0,0 +1,7 @@ +{ + "name": "application-name", + "version": "0.0.1", + "ava": { + "files": "dir-a/*.js" + } +} diff --git a/test/fork.js b/test/fork.js index 92c6ee2e6..5c99e35f8 100644 --- a/test/fork.js +++ b/test/fork.js @@ -3,6 +3,7 @@ var path = require('path'); var test = require('tap').test; var _fork = require('../lib/fork.js'); var CachingPrecompiler = require('../lib/caching-precompiler'); + var cacheDir = path.join(__dirname, '../node_modules/.cache/ava'); var precompiler = new CachingPrecompiler(cacheDir); diff --git a/test/hooks.js b/test/hooks.js index a2cf57799..38163f48b 100644 --- a/test/hooks.js +++ b/test/hooks.js @@ -4,6 +4,7 @@ var test = require('tap').test; var Runner = require('../lib/runner'); var _fork = require('../lib/fork.js'); var CachingPrecompiler = require('../lib/caching-precompiler'); + var cacheDir = path.join(__dirname, '../node_modules/.cache/ava'); var precompiler = new CachingPrecompiler(cacheDir); diff --git a/test/profile.js b/test/profile.js index 10972ea87..fbf1f21ce 100644 --- a/test/profile.js +++ b/test/profile.js @@ -22,8 +22,8 @@ function run(files) { test('exits normally when tests pass', function (t) { t.plan(1); run('es2015') - .catch(function (e) { - t.fail(e); + .catch(function (err) { + t.fail(err); }) .then(function () { t.pass(); diff --git a/test/reporters/mini.js b/test/reporters/mini.js index c55813d75..265d1e18b 100644 --- a/test/reporters/mini.js +++ b/test/reporters/mini.js @@ -213,7 +213,10 @@ test('results with passing known failure tests', function (t) { reporter.failCount = 0; var runStatus = { - knownFailures: [{title: 'known failure', failing: true}] + knownFailures: [{ + title: 'known failure', + failing: true + }] }; var actualOutput = reporter.finish(runStatus); var expectedOutput = [ diff --git a/test/reporters/verbose.js b/test/reporters/verbose.js index 83d5c92a4..5dc55523b 100644 --- a/test/reporters/verbose.js +++ b/test/reporters/verbose.js @@ -233,7 +233,10 @@ test('results with passing known failure tests', function (t) { var runStatus = createRunStatus(); runStatus.passCount = 1; runStatus.knownFailureCount = 1; - runStatus.knownFailures = [{title: 'known failure', failing: true}]; + runStatus.knownFailures = [{ + title: 'known failure', + failing: true + }]; var actualOutput = reporter.finish(runStatus); var expectedOutput = [ diff --git a/test/runner.js b/test/runner.js index 03b3e7d52..37df7938e 100644 --- a/test/runner.js +++ b/test/runner.js @@ -160,11 +160,26 @@ test('test types and titles', function (t) { runner.test('test', fn); var tests = [ - {type: 'before', title: 'named'}, - {type: 'beforeEach', title: 'beforeEach for test'}, - {type: 'test', title: 'test'}, - {type: 'afterEach', title: 'named for test'}, - {type: 'after', title: 'after'} + { + type: 'before', + title: 'named' + }, + { + type: 'beforeEach', + title: 'beforeEach for test' + }, + { + type: 'test', + title: 'test' + }, + { + type: 'afterEach', + title: 'named for test' + }, + { + type: 'after', + title: 'after' + } ]; runner.on('test', function (props) { @@ -364,7 +379,10 @@ test('options.bail will bail out (async)', function (t) { test('options.bail + serial - tests will never happen (async)', function (t) { t.plan(2); - var runner = new Runner({bail: true, serial: true}); + var runner = new Runner({ + bail: true, + serial: true + }); var tests = []; runner.cb(function (a) { diff --git a/test/sequence.js b/test/sequence.js index 0cfc6fcdb..cfa3e5b61 100644 --- a/test/sequence.js +++ b/test/sequence.js @@ -69,9 +69,18 @@ test('all sync - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -91,9 +100,18 @@ test('all sync - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -113,9 +131,18 @@ test('all sync - begin failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -135,9 +162,17 @@ test('all sync - mid failure - no bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a'}, + { + passed: false, + reason: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -157,9 +192,18 @@ test('all sync - end failure - no bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -179,9 +223,18 @@ test('all sync - multiple failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -201,7 +254,10 @@ test('all sync - begin failure - bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'} + { + passed: false, + reason: 'a' + } ] }); t.end(); @@ -221,8 +277,14 @@ test('all sync - mid failure - bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'} + { + passed: true, + result: 'a' + }, + { + passed: false, + reason: 'b' + } ] }); t.end(); @@ -242,9 +304,18 @@ test('all sync - end failure - bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -263,9 +334,18 @@ test('all async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -285,9 +365,18 @@ test('all async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -307,9 +396,18 @@ test('last async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -329,9 +427,18 @@ test('mid async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -351,9 +458,18 @@ test('first async - no failure - no bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -373,9 +489,18 @@ test('last async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -395,9 +520,18 @@ test('mid async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -417,9 +551,18 @@ test('first async - no failure - bail', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -439,7 +582,10 @@ test('all async - begin failure - bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'} + { + passed: false, + reason: 'a' + } ] }); t.end(); @@ -459,8 +605,14 @@ test('all async - mid failure - bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'} + { + passed: true, + result: 'a' + }, + { + passed: false, + reason: 'b' + } ] }); t.end(); @@ -480,9 +632,18 @@ test('all async - end failure - bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -502,9 +663,18 @@ test('all async - begin failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: true, result: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -524,9 +694,18 @@ test('all async - mid failure - no bail', function (t) { passed: false, reason: 'b', result: [ - {passed: true, result: 'a'}, - {passed: false, reason: 'b'}, - {passed: true, result: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: false, + reason: 'b' + }, + { + passed: true, + result: 'c' + } ] }); t.end(); @@ -546,9 +725,18 @@ test('all async - end failure - no bail', function (t) { passed: false, reason: 'c', result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -568,9 +756,18 @@ test('all async - multiple failure - no bail', function (t) { passed: false, reason: 'a', result: [ - {passed: false, reason: 'a'}, - {passed: true, result: 'b'}, - {passed: false, reason: 'c'} + { + passed: false, + reason: 'a' + }, + { + passed: true, + result: 'b' + }, + { + passed: false, + reason: 'c' + } ] }); t.end(); @@ -585,8 +782,8 @@ test('rejections are just passed through - no bail', function (t) { reject('foo') ], false - ).run().catch(function (reason) { - t.is(reason, 'foo'); + ).run().catch(function (err) { + t.is(err, 'foo'); t.end(); }); }); @@ -599,8 +796,8 @@ test('rejections are just passed through - bail', function (t) { reject('foo') ], true - ).run().catch(function (reason) { - t.is(reason, 'foo'); + ).run().catch(function (err) { + t.is(err, 'foo'); t.end(); }); }); @@ -634,15 +831,24 @@ test('sequences of sequences', function (t) { passed: true, reason: null, result: [ - {passed: true, result: 'a'}, - {passed: true, result: 'b'} + { + passed: true, + result: 'a' + }, + { + passed: true, + result: 'b' + } ] }, { passed: true, reason: null, result: [ - {passed: true, result: 'c'} + { + passed: true, + result: 'c' + } ] } ] diff --git a/test/test-collection.js b/test/test-collection.js index c28932b29..bb9cda357 100644 --- a/test/test-collection.js +++ b/test/test-collection.js @@ -90,7 +90,10 @@ test('must be called with new', function (t) { test('throws if no type is supplied', function (t) { var collection = new TestCollection(); t.throws(function () { - collection.add({title: 'someTitle', metadata: {}}); + collection.add({ + title: 'someTitle', + metadata: {} + }); }, {message: 'Test type must be specified'}); t.end(); }); @@ -98,7 +101,10 @@ test('throws if no type is supplied', function (t) { test('throws if you try to set a hook as exclusive', function (t) { var collection = new TestCollection(); t.throws(function () { - collection.add(mockTest({type: 'beforeEach', exclusive: true})); + collection.add(mockTest({ + type: 'beforeEach', + exclusive: true + })); }, {message: '"only" cannot be used with a beforeEach hook'}); t.end(); }); @@ -106,7 +112,10 @@ test('throws if you try to set a hook as exclusive', function (t) { test('throws if you try to set a before hook as always', function (t) { var collection = new TestCollection(); t.throws(function () { - collection.add(mockTest({type: 'before', always: true})); + collection.add(mockTest({ + type: 'before', + always: true + })); }, {message: '"always" can only be used with after and afterEach hooks'}); t.end(); }); @@ -184,7 +193,10 @@ test('adding a after test', function (t) { test('adding a after.always test', function (t) { var collection = new TestCollection(); - collection.add(mockTest({type: 'after', always: true}, 'bar')); + collection.add(mockTest({ + type: 'after', + always: true + }, 'bar')); t.strictDeepEqual(serialize(collection), { hooks: { afterAlways: ['bar'] @@ -206,7 +218,10 @@ test('adding a afterEach test', function (t) { test('adding a afterEach.always test', function (t) { var collection = new TestCollection(); - collection.add(mockTest({type: 'afterEach', always: true}, 'baz')); + collection.add(mockTest({ + type: 'afterEach', + always: true + }, 'baz')); t.strictDeepEqual(serialize(collection), { hooks: { afterEachAlways: ['baz'] @@ -252,12 +267,18 @@ test('foo', function (t) { } add('after1', {type: 'after'}); - add('after.always', {type: 'after', always: true}); + add('after.always', { + type: 'after', + always: true + }); add('beforeEach1', {type: 'beforeEach'}); add('before1', {type: 'before'}); add('beforeEach2', {type: 'beforeEach'}); add('afterEach1', {type: 'afterEach'}); - add('afterEach.always', {type: 'afterEach', always: true}); + add('afterEach.always', { + type: 'afterEach', + always: true + }); add('test1', {}); add('afterEach2', {type: 'afterEach'}); add('test2', {}); @@ -312,12 +333,18 @@ test('foo', function (t) { } add('after1', {type: 'after'}); - add('after.always', {type: 'after', always: true}); + add('after.always', { + type: 'after', + always: true + }); add('beforeEach1', {type: 'beforeEach'}); add('before1', {type: 'before'}); add('beforeEach2', {type: 'beforeEach'}); add('afterEach1', {type: 'afterEach'}); - add('afterEach.always', {type: 'afterEach', always: true}); + add('afterEach.always', { + type: 'afterEach', + always: true + }); add('test1', {}); add('afterEach2', {type: 'afterEach'}); add('test2', {}); diff --git a/test/test.js b/test/test.js index 09efdeb64..6fb41cd9f 100644 --- a/test/test.js +++ b/test/test.js @@ -9,25 +9,41 @@ var failingTestHint = 'Test was expected to fail, but succeeded, you should stop function ava(title, fn, contextRef, report) { var t = new Test(title, fn, contextRef, report); - t.metadata = {callback: false}; + t.metadata = { + callback: false + }; return t; } ava.failing = function (title, fn, contextRef, report) { var t = new Test(title, fn, contextRef, report); - t.metadata = {callback: false, failing: true}; + + t.metadata = { + callback: false, + failing: true + }; + return t; }; ava.cb = function (title, fn, contextRef, report) { var t = new Test(title, fn, contextRef, report); - t.metadata = {callback: true}; + + t.metadata = { + callback: true + }; + return t; }; ava.cb.failing = function (title, fn, contextRef, report) { var t = new Test(title, fn, contextRef, report); - t.metadata = {callback: true, failing: true}; + + t.metadata = { + callback: true, + failing: true + }; + return t; }; @@ -74,6 +90,7 @@ test('infer name from function', function (t) { var result = ava(function foo(a) { a.pass(); }).run(); + t.is(result.passed, true); t.is(result.result.title, 'foo'); t.end(); @@ -200,7 +217,13 @@ test('handle falsy testing of arrays', function (t) { test('handle testing of objects', function (t) { var result = ava(function (a) { - a.deepEqual({foo: 'foo', bar: 'bar'}, {foo: 'foo', bar: 'bar'}); + a.deepEqual({ + foo: 'foo', + bar: 'bar' + }, { + foo: 'foo', + bar: 'bar' + }); }).run(); t.is(result.passed, true); @@ -210,7 +233,14 @@ test('handle testing of objects', function (t) { test('handle falsy testing of objects', function (t) { var result = ava(function (a) { - a.notDeepEqual({foo: 'foo', bar: 'bar'}, {foo: 'foo', bar: 'bar', cat: 'cake'}); + a.notDeepEqual({ + foo: 'foo', + bar: 'bar' + }, { + foo: 'foo', + bar: 'bar', + cat: 'cake' + }); }).run(); t.is(result.passed, true); diff --git a/test/visual/print-lorem-ipsum.js b/test/visual/print-lorem-ipsum.js index 8d1aed5cc..ba955d229 100644 --- a/test/visual/print-lorem-ipsum.js +++ b/test/visual/print-lorem-ipsum.js @@ -1,8 +1,8 @@ 'use strict'; var fs = require('fs'); var path = require('path'); -var text = fs.readFileSync(path.join(__dirname, 'lorem-ipsum.txt'), 'utf8'); +var text = fs.readFileSync(path.join(__dirname, 'lorem-ipsum.txt'), 'utf8'); var lines = text.split(/\r?\n/g).map(function (line) { return line.split(' '); }); diff --git a/test/visual/run-visual-tests.js b/test/visual/run-visual-tests.js index 463a1fd3f..7ab61de8f 100644 --- a/test/visual/run-visual-tests.js +++ b/test/visual/run-visual-tests.js @@ -7,6 +7,7 @@ var arrify = require('arrify'); var Promise = require('bluebird'); var pify = require('pify'); var inquirer = pify(require('inquirer'), Promise); + var cwd = path.resolve(__dirname, '../../'); function fixture(fixtureName) { diff --git a/test/watcher.js b/test/watcher.js index 993fd2729..a835940da 100644 --- a/test/watcher.js +++ b/test/watcher.js @@ -8,7 +8,7 @@ var lolex = require('lolex'); var proxyquire = require('proxyquire'); var sinon = require('sinon'); var test = require('tap').test; -var AvaFiles = require('../lib/ava-files'); +var AvaFiles = require('ava-files'); var setImmediate = require('../lib/globals').setImmediate; @@ -36,22 +36,7 @@ function makeGroup(test) { } var group = makeGroup(test); -test('chokidar is not installed', function (t) { - t.plan(2); - - var Subject = proxyquire.noCallThru().load('../lib/watcher', { - chokidar: null - }); - - try { - new Subject({}, {excludePatterns: [], on: function () {}}, [], []); // eslint-disable-line - } catch (err) { - t.is(err.name, 'AvaError'); - t.is(err.message, 'The optional dependency chokidar failed to install and is required for --watch. Chokidar is likely not supported on your platform.'); - } -}); - -group('chokidar is installed', function (beforeEach, test, group) { +group('chokidar', function (beforeEach, test, group) { var chokidar; var debug; var logger; @@ -76,7 +61,7 @@ group('chokidar is installed', function (beforeEach, test, group) { debug.apply(null, args); }; }, - './ava-files': avaFiles + 'ava-files': avaFiles }); } @@ -101,13 +86,19 @@ group('chokidar is installed', function (beforeEach, test, group) { }; resetRunStatus = function () { - runStatus = {failCount: 0, rejectionCount: 0, exceptionCount: 0}; + runStatus = { + failCount: 0, + rejectionCount: 0, + exceptionCount: 0 + }; + return runStatus; }; if (clock) { clock.uninstall(); } + clock = lolex.install(0, ['setImmediate', 'setTimeout', 'clearTimeout']); chokidarEmitter = new EventEmitter(); @@ -243,9 +234,21 @@ group('chokidar is installed', function (beforeEach, test, group) { }); [ - {label: 'is added', fire: add, event: 'add'}, - {label: 'changes', fire: change, event: 'change'}, - {label: 'is removed', fire: unlink, event: 'unlink'} + { + label: 'is added', + fire: add, + event: 'add' + }, + { + label: 'changes', + fire: change, + event: 'change' + }, + { + label: 'is removed', + fire: unlink, + event: 'unlink' + } ].forEach(function (variant) { test('logs a debug message when a file is ' + variant.label, function (t) { t.plan(2); @@ -258,9 +261,18 @@ group('chokidar is installed', function (beforeEach, test, group) { }); [ - {label: 'is added', fire: add}, - {label: 'changes', fire: change}, - {label: 'is removed', fire: unlink} + { + label: 'is added', + fire: add + }, + { + label: 'changes', + fire: change + }, + { + label: 'is removed', + fire: unlink + } ].forEach(function (variant) { test('reruns initial tests when a source file ' + variant.label, function (t) { t.plan(12); @@ -305,9 +317,18 @@ group('chokidar is installed', function (beforeEach, test, group) { }); [ - {label: 'failures', prop: 'failCount'}, - {label: 'rejections', prop: 'rejectionCount'}, - {label: 'exceptions', prop: 'exceptionCount'} + { + label: 'failures', + prop: 'failCount' + }, + { + label: 'rejections', + prop: 'rejectionCount' + }, + { + label: 'exceptions', + prop: 'exceptionCount' + } ].forEach(function (variant) { test('does not clear logger if the previous run had ' + variant.label, function (t) { t.plan(2); @@ -460,8 +481,14 @@ group('chokidar is installed', function (beforeEach, test, group) { }); [ - {label: 'is added', fire: add}, - {label: 'changes', fire: change} + { + label: 'is added', + fire: add + }, + { + label: 'changes', + fire: change + } ].forEach(function (variant) { test('(re)runs a test file when it ' + variant.label, function (t) { t.plan(6); @@ -553,8 +580,8 @@ group('chokidar is installed', function (beforeEach, test, group) { test('initial exclude patterns override whether something is a test file', function (t) { t.plan(2); - avaFiles = function (files, sources) { - var ret = new AvaFiles(files, sources); + avaFiles = function (options) { + var ret = new AvaFiles(options); // Note: There is no way for users to actually set exclude patterns yet. // This test just validates that internal updates to the default excludes pattern will be obeyed. ret.excludePatterns = ['!*bar*']; @@ -632,8 +659,8 @@ group('chokidar is installed', function (beforeEach, test, group) { test('exclude patterns override directory matches', function (t) { t.plan(2); - avaFiles = function (files, sources) { - var ret = new AvaFiles(files, sources); + avaFiles = function (options) { + var ret = new AvaFiles(options); // Note: There is no way for users to actually set exclude patterns yet. // This test just validates that internal updates to the default excludes pattern will be obeyed. ret.excludePatterns = ['!**/exclude/**']; @@ -1100,7 +1127,10 @@ group('chokidar is installed', function (beforeEach, test, group) { }); var emitStats = function (file, hasExclusive) { - apiEmitter.emit('stats', {file: file, hasExclusive: hasExclusive}); + apiEmitter.emit('stats', { + file: file, + hasExclusive: hasExclusive + }); }; var t1 = path.join('test', '1.js'); @@ -1267,8 +1297,15 @@ group('chokidar is installed', function (beforeEach, test, group) { var other; seed(function (files) { - runStatusEmitter.emit('test', {file: files[0], error: {}}); - runStatusEmitter.emit('error', {file: files[0]}); + runStatusEmitter.emit('test', { + file: files[0], + error: {} + }); + + runStatusEmitter.emit('error', { + file: files[0] + }); + other = files[1]; }); @@ -1281,9 +1318,15 @@ group('chokidar is installed', function (beforeEach, test, group) { t.plan(1); var first; + seed(function (files) { - runStatusEmitter.emit('test', {file: files[0], error: {}}); + runStatusEmitter.emit('test', { + file: files[0], + error: {} + }); + runStatusEmitter.emit('error', {file: files[1]}); + first = files[0]; }); @@ -1296,9 +1339,15 @@ group('chokidar is installed', function (beforeEach, test, group) { t.plan(1); var same; + seed(function (files) { - runStatusEmitter.emit('test', {file: files[0], error: {}}); + runStatusEmitter.emit('test', { + file: files[0], + error: {} + }); + runStatusEmitter.emit('error', {file: files[0]}); + same = files[0]; }); @@ -1312,14 +1361,21 @@ group('chokidar is installed', function (beforeEach, test, group) { var same; var other; + seed(function (files) { - runStatusEmitter.emit('test', {file: files[0], error: {}}); + runStatusEmitter.emit('test', { + file: files[0], + error: {} + }); + runStatusEmitter.emit('error', {file: files[0]}); + same = files[0]; other = files[1]; }); unlink(same); + return debounce().then(function () { return rerun(other); }).then(function () { From f4a179c572c3b0d40ccdebb90c020fb08f823c3a Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Wed, 29 Jun 2016 10:50:06 -0400 Subject: [PATCH 13/14] on => in --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index d8d19f553..fb9da098a 100644 --- a/readme.md +++ b/readme.md @@ -970,7 +970,7 @@ As of version `5.0.0` it uses source maps to report coverage for your actual cod ### Common pitfalls -We have a growing list of [common pitfalls](docs/common-pitfalls.md) you may experience while using AVA. If you encounter any issues you think are common, comment on [this issue](https://github.com/avajs/ava/issues/404). +We have a growing list of [common pitfalls](docs/common-pitfalls.md) you may experience while using AVA. If you encounter any issues you think are common, comment in [this issue](https://github.com/avajs/ava/issues/404). ## FAQ From 691cecc6f58403d518e0d6ee17acecd01bcbe289 Mon Sep 17 00:00:00 2001 From: Juan Soto Date: Thu, 30 Jun 2016 11:30:19 -0400 Subject: [PATCH 14/14] Fix spacing --- readme.md | 118 +++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/readme.md b/readme.md index fb9da098a..4c93eb77f 100644 --- a/readme.md +++ b/readme.md @@ -134,33 +134,33 @@ AVA comes with an intelligent watch mode. [Learn more in its recipe](docs/recipe ```console $ ava --help - Usage - ava [ ...] - - Options - --init Add AVA to your project - --fail-fast Stop after first test failure - --serial, -s Run tests serially - --require, -r Module to preload (Can be repeated) - --tap, -t Generate TAP output - --verbose, -v Enable verbose output - --no-cache Disable the transpiler cache - --match, -m Only run tests with matching title (Can be repeated) - --watch, -w Re-run tests when tests and source files change - --source, -S Pattern to match source files so tests can be re-run (Can be repeated) - --timeout, -T Set global timeout - --concurrency, -c Maximum number of test files running at the same time (EXPERIMENTAL) - - Examples - ava - ava test.js test2.js - ava test-*.js - ava test - ava --init - ava --init foo.js - - Default patterns when no arguments: - test.js test-*.js test/**/*.js **/__tests__/**/*.js **/*.test.js + Usage + ava [ ...] + + Options + --init Add AVA to your project + --fail-fast Stop after first test failure + --serial, -s Run tests serially + --require, -r Module to preload (Can be repeated) + --tap, -t Generate TAP output + --verbose, -v Enable verbose output + --no-cache Disable the transpiler cache + --match, -m Only run tests with matching title (Can be repeated) + --watch, -w Re-run tests when tests and source files change + --source, -S Pattern to match source files so tests can be re-run (Can be repeated) + --timeout, -T Set global timeout + --concurrency, -c Maximum number of test files running at the same time (EXPERIMENTAL) + + Examples + ava + ava test.js test2.js + ava test-*.js + ava test + ava --init + ava --init foo.js + + Default patterns when no arguments: + test.js test-*.js test/**/*.js **/__tests__/**/*.js **/*.test.js ``` *Note that the CLI will use your local install of AVA when available, even when run globally.* @@ -175,27 +175,27 @@ All of the CLI options can be configured in the `ava` section of your `package.j ```json { - "ava": { - "files": [ - "my-test-folder/*.js", - "!**/not-this-file.js" - ], - "source": [ - "**/*.{js,jsx}", - "!dist/**/*" - ], - "match": [ - "*oo", - "!foo" - ], - "concurrency": 5, - "failFast": true, - "tap": true, - "require": [ - "babel-register" - ], - "babel": "inherit" - } + "ava": { + "files": [ + "my-test-folder/*.js", + "!**/not-this-file.js" + ], + "source": [ + "**/*.{js,jsx}", + "!dist/**/*" + ], + "match": [ + "*oo", + "!foo" + ], + "concurrency": 5, + "failFast": true, + "tap": true, + "require": [ + "babel-register" + ], + "babel": "inherit" + } } ``` @@ -612,14 +612,14 @@ The corresponding Babel config for AVA's setup is as follows: ```json { - "presets": [ - "es2015", - "stage-2" - ], - "plugins": [ - "espower", - "transform-runtime" - ] + "presets": [ + "es2015", + "stage-2" + ], + "plugins": [ + "espower", + "transform-runtime" + ] } ``` @@ -937,9 +937,9 @@ Will output: ``` t.true(a.test(b) || b === c) - | | | | - | "bar" "bar" "baz" - false + | | | | + | "bar" "bar" "baz" + false ``` ## Process isolation