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