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.

104 lines
2.1 KiB
JavaScript

'use strict';
var isPromise = require('is-promise');
var AvaError = require('./ava-error');
function noop() {}
module.exports = Sequence;
function Sequence(tests, bail) {
if (!(this instanceof Sequence)) {
throw new TypeError('Class constructor Sequence cannot be invoked without \'new\'');
}
if (!tests) {
throw new Error('Sequence items can\'t be undefined');
}
this.results = [];
this.passed = true;
this.reason = null;
this.tests = tests;
this.bail = bail || false;
// TODO(vdemedes): separate into a utility (it's being used in serveral places)
Object.keys(Sequence.prototype).forEach(function (key) {
this[key] = this[key].bind(this);
}, this);
}
Sequence.prototype.run = function () {
var length = this.tests.length;
for (var i = 0; i < length; i++) {
// if last item failed and we should bail, return results and stop
if (this.bail && !this.passed) {
return this._results();
}
var result = this.tests[i].run();
// if a Promise returned, we don't need to check for Promises after this test
// so we can just use Promise.each() on the rest of the tests
if (isPromise(result)) {
return result
.then(this._addResult)
.return(this.tests.slice(i + 1))
.each(this._runTest)
.catch(AvaError, noop)
.then(this._results);
}
try {
this._addResult(result);
} catch (err) {
// in bail mode, don't execute the next tests
if (err instanceof AvaError) {
return this._results();
}
throw err;
}
}
return this._results();
};
Sequence.prototype._runTest = function (test) {
var result = test.run();
if (isPromise(result)) {
return result
.then(this._addResult);
}
return this._addResult(result);
};
Sequence.prototype._addResult = function (result) {
this.results.push(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 Sequence while in bail mode');
}
}
return result;
};
Sequence.prototype._results = function () {
return {
passed: this.passed,
reason: this.reason,
result: this.results
};
};