95 lines
1.9 KiB
JavaScript
95 lines
1.9 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const beforeExitSubscribers = new Set();
|
||
|
const beforeExitHandler = () => {
|
||
|
for (const subscriber of beforeExitSubscribers) {
|
||
|
subscriber();
|
||
|
}
|
||
|
};
|
||
|
const onBeforeExit = subscriber => {
|
||
|
if (beforeExitSubscribers.size === 0) {
|
||
|
// Only listen for the event once, no matter how many Sequences are run
|
||
|
// concurrently.
|
||
|
process.on('beforeExit', beforeExitHandler);
|
||
|
}
|
||
|
|
||
|
beforeExitSubscribers.add(subscriber);
|
||
|
return {
|
||
|
dispose() {
|
||
|
beforeExitSubscribers.delete(subscriber);
|
||
|
if (beforeExitSubscribers.size === 0) {
|
||
|
process.removeListener('beforeExit', beforeExitHandler);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
class Sequence {
|
||
|
constructor(runnables, bail) {
|
||
|
if (!Array.isArray(runnables)) {
|
||
|
throw new TypeError('Expected an array of runnables');
|
||
|
}
|
||
|
|
||
|
this.runnables = runnables;
|
||
|
this.bail = bail || false;
|
||
|
}
|
||
|
|
||
|
run() {
|
||
|
const iterator = this.runnables[Symbol.iterator]();
|
||
|
|
||
|
let activeRunnable;
|
||
|
const beforeExit = onBeforeExit(() => {
|
||
|
if (activeRunnable.finishDueToInactivity) {
|
||
|
activeRunnable.finishDueToInactivity();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
let allPassed = true;
|
||
|
const finish = () => {
|
||
|
beforeExit.dispose();
|
||
|
return allPassed;
|
||
|
};
|
||
|
|
||
|
const runNext = () => {
|
||
|
let promise;
|
||
|
|
||
|
for (let next = iterator.next(); !next.done; next = iterator.next()) {
|
||
|
activeRunnable = next.value;
|
||
|
const passedOrPromise = activeRunnable.run();
|
||
|
if (!passedOrPromise) {
|
||
|
allPassed = false;
|
||
|
|
||
|
if (this.bail) {
|
||
|
// Stop if the test failed and bail mode is on.
|
||
|
break;
|
||
|
}
|
||
|
} else if (passedOrPromise !== true) {
|
||
|
promise = passedOrPromise;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!promise) {
|
||
|
return finish();
|
||
|
}
|
||
|
|
||
|
return promise.then(passed => {
|
||
|
if (!passed) {
|
||
|
allPassed = false;
|
||
|
|
||
|
if (this.bail) {
|
||
|
// Stop if the test failed and bail mode is on.
|
||
|
return finish();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return runNext();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return runNext();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = Sequence;
|