You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
1.9 KiB
JavaScript

'use strict';
var Promise = require('bluebird');
var isPromise = require('is-promise');
var AvaError = require('./ava-error');
function noop() {}
module.exports = Concurrent;
function Concurrent(tests, bail) {
if (!(this instanceof Concurrent)) {
throw new TypeError('Class constructor Concurrent cannot be invoked without \'new\'');
}
if (!Array.isArray(tests)) {
throw new TypeError('Expected an array of tests');
}
this.results = [];
this.passed = true;
this.reason = null;
this.tests = tests;
this.bail = bail || false;
Object.keys(Concurrent.prototype).forEach(function (key) {
this[key] = this[key].bind(this);
}, this);
}
Concurrent.prototype.run = function () {
var results;
try {
results = this.tests.map(this._runTest);
} catch (err) {
if (err instanceof AvaError) {
return this._results();
}
throw err;
}
var isAsync = results.some(isPromise);
if (isAsync) {
return Promise.all(results)
.catch(AvaError, noop)
.then(this._results);
}
return this._results();
};
Concurrent.prototype._runTest = function (test, index) {
var result = test.run();
if (isPromise(result)) {
var self = this;
return result.then(function (result) {
return self._addResult(result, index);
});
}
return this._addResult(result, index);
};
Concurrent.prototype._addResult = function (result, index) {
// always save result when not in bail mode or all previous tests pass
if ((this.bail && this.passed) || !this.bail) {
this.results[index] = result;
}
if (result.passed === false) {
this.passed = false;
// only set reason once
if (!this.reason) {
this.reason = result.reason;
}
if (this.bail) {
throw new AvaError('Error in Concurrent while in bail mode');
}
}
return result;
};
Concurrent.prototype._results = function () {
return {
passed: this.passed,
reason: this.reason,
result: this.results
};
};