aboutsummaryrefslogtreecommitdiff
path: root/node_modules/ava/api.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/ava/api.js')
-rw-r--r--node_modules/ava/api.js99
1 files changed, 20 insertions, 79 deletions
diff --git a/node_modules/ava/api.js b/node_modules/ava/api.js
index 99213a757..9c6e775d6 100644
--- a/node_modules/ava/api.js
+++ b/node_modules/ava/api.js
@@ -2,9 +2,11 @@
const EventEmitter = require('events');
const path = require('path');
const fs = require('fs');
+const os = require('os');
const commonPathPrefix = require('common-path-prefix');
const uniqueTempDir = require('unique-temp-dir');
const findCacheDir = require('find-cache-dir');
+const isCi = require('is-ci');
const resolveCwd = require('resolve-cwd');
const debounce = require('lodash.debounce');
const autoBind = require('auto-bind');
@@ -53,6 +55,7 @@ class Api extends EventEmitter {
this.options = Object.assign({match: []}, options);
this.options.require = resolveModules(this.options.require);
}
+
_runFile(file, runStatus, execArgv) {
const hash = this.precompiler.precompileFile(file);
const precompiled = Object.assign({}, this._precompiledHelpers);
@@ -69,17 +72,20 @@ class Api extends EventEmitter {
return emitter;
}
+
run(files, options) {
return new AvaFiles({cwd: this.options.resolveTestsFrom, files})
.findTestFiles()
.then(files => this._run(files, options));
}
+
_onTimeout(runStatus) {
const timeout = ms(this.options.timeout);
const err = new AvaError(`Exited because no new tests completed within the last ${timeout}ms of inactivity`);
this._handleError(runStatus, err);
runStatus.emit('timeout');
}
+
_setupTimeout(runStatus) {
const timeout = ms(this.options.timeout);
@@ -90,9 +96,11 @@ class Api extends EventEmitter {
runStatus._restartTimer();
runStatus.on('test', runStatus._restartTimer);
}
+
_cancelTimeout(runStatus) {
runStatus._restartTimer.cancel();
}
+
_setupPrecompiler(files) {
const isCacheEnabled = this.options.cacheEnabled !== false;
let cacheDir = uniqueTempDir();
@@ -119,6 +127,7 @@ class Api extends EventEmitter {
});
});
}
+
_precompileHelpers() {
this._precompiledHelpers = {};
@@ -134,6 +143,7 @@ class Api extends EventEmitter {
this._precompiledHelpers[file] = hash;
});
}
+
_run(files, options) {
options = options || {};
@@ -160,18 +170,20 @@ class Api extends EventEmitter {
this._setupTimeout(runStatus);
}
- let overwatch;
+ let concurrency = Math.min(os.cpus().length, isCi ? 2 : Infinity);
+
if (this.options.concurrency > 0) {
- const concurrency = this.options.serial ? 1 : this.options.concurrency;
- overwatch = this._runWithPool(files, runStatus, concurrency);
- } else {
- // _runWithoutPool exists to preserve legacy behavior, specifically around `.only`
- overwatch = this._runWithoutPool(files, runStatus);
+ concurrency = this.options.concurrency;
+ }
+
+ if (this.options.serial) {
+ concurrency = 1;
}
- return overwatch;
+ return this._runWithPool(files, runStatus, concurrency);
});
}
+
_computeForkExecArgs(files) {
const execArgv = this.options.testOnlyExecArgv || process.execArgv;
let debugArgIndex = -1;
@@ -217,85 +229,14 @@ class Api extends EventEmitter {
return forkExecArgv;
});
}
+
_handleError(runStatus, err) {
runStatus.handleExceptions({
exception: err,
file: err.file ? path.relative(process.cwd(), err.file) : undefined
});
}
- _runWithoutPool(files, runStatus) {
- const tests = [];
- let execArgvList;
-
- // TODO: This should be cleared at the end of the run
- runStatus.on('timeout', () => {
- tests.forEach(fork => {
- fork.exit();
- });
- });
- return this._computeForkExecArgs(files)
- .then(argvList => {
- execArgvList = argvList;
- })
- .return(files)
- .each((file, index) => {
- return new Promise(resolve => {
- const forkArgs = execArgvList[index];
- const test = this._runFile(file, runStatus, forkArgs);
- tests.push(test);
- test.on('stats', resolve);
- test.catch(resolve);
- }).catch(err => {
- err.results = [];
- err.file = file;
- return Promise.reject(err);
- });
- })
- .then(() => {
- if (this.options.match.length > 0 && !runStatus.hasExclusive) {
- const err = new AvaError('Couldn\'t find any matching tests');
- err.file = undefined;
- err.results = [];
- return Promise.reject(err);
- }
-
- const method = this.options.serial ? 'mapSeries' : 'map';
- const options = {
- runOnlyExclusive: runStatus.hasExclusive
- };
-
- return Promise[method](files, (file, index) => {
- return tests[index].run(options).catch(err => {
- err.file = file;
- this._handleError(runStatus, err);
- return getBlankResults();
- });
- });
- })
- .catch(err => {
- this._handleError(runStatus, err);
- return err.results;
- })
- .tap(results => {
- // If no tests ran, make sure to tear down the child processes
- if (results.length === 0) {
- tests.forEach(test => {
- test.send('teardown');
- });
- }
- })
- .then(results => {
- // Cancel debounced _onTimeout() from firing
- if (this.options.timeout) {
- this._cancelTimeout(runStatus);
- }
-
- runStatus.processResults(results);
-
- return runStatus;
- });
- }
_runWithPool(files, runStatus, concurrency) {
const tests = [];
let execArgvList;