diff options
Diffstat (limited to 'node_modules/ava/api.js')
-rw-r--r-- | node_modules/ava/api.js | 99 |
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; |