aboutsummaryrefslogtreecommitdiff
path: root/node_modules/ava/lib/sequence.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/ava/lib/sequence.js')
-rw-r--r--node_modules/ava/lib/sequence.js94
1 files changed, 94 insertions, 0 deletions
diff --git a/node_modules/ava/lib/sequence.js b/node_modules/ava/lib/sequence.js
new file mode 100644
index 000000000..1e5960a98
--- /dev/null
+++ b/node_modules/ava/lib/sequence.js
@@ -0,0 +1,94 @@
+'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;