Moved fn skipping policy out of QueueRunner

This should allow us to more easily support complex skipping strategies
like skipping nested cleanup fns when the corresponding befores were
skipped, or skipping specs and suites when a beforeAll fails.

* #1533
This commit is contained in:
Steve Gravrock
2021-09-29 12:14:07 -07:00
parent 457a2727ba
commit 5eaeeb0b6c
8 changed files with 228 additions and 57 deletions

View File

@@ -0,0 +1,19 @@
getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
function CompleteOnFirstErrorSkipPolicy(queueableFns, firstCleanupIx) {
this.queueableFns_ = queueableFns;
this.firstCleanupIx_ = firstCleanupIx;
}
CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(
lastRanFnIx,
errored
) {
if (errored && lastRanFnIx < this.firstCleanupIx_) {
return this.firstCleanupIx_;
} else {
return lastRanFnIx + 1;
}
};
return CompleteOnFirstErrorSkipPolicy;
};

View File

@@ -502,12 +502,17 @@ getJasmineRequireObj().Env = function(j$) {
};
var queueRunnerFactory = function(options, args) {
var failFast = false;
if (options.isLeaf) {
failFast = true;
} else if (!options.isReporter) {
failFast = config.stopOnSpecFailure;
if (
// A spec
options.isLeaf ||
// A suite, and config.stopOnSpecFailure is set
(!options.isLeaf && !options.isReporter && config.stopOnSpecFailure)
) {
options.SkipPolicy = j$.CompleteOnFirstErrorSkipPolicy;
} else {
options.SkipPolicy = j$.NeverSkipPolicy;
}
options.clearStack = options.clearStack || clearStack;
options.timeout = {
setTimeout: realSetTimeout,
@@ -515,7 +520,6 @@ getJasmineRequireObj().Env = function(j$) {
};
options.fail = self.fail;
options.globalErrors = globalErrors;
options.completeOnFirstError = failFast;
options.onException =
options.onException ||
function(e) {

View File

@@ -0,0 +1,9 @@
getJasmineRequireObj().NeverSkipPolicy = function(j$) {
function NeverSkipPolicy(queueableFns, firstCleanupIx) {}
NeverSkipPolicy.prototype.skipTo = function(lastRanFnIx, errored) {
return lastRanFnIx + 1;
};
return NeverSkipPolicy;
};

View File

@@ -56,7 +56,9 @@ getJasmineRequireObj().QueueRunner = function(j$) {
pushListener: emptyFn,
popListener: emptyFn
};
this.completeOnFirstError = !!attrs.completeOnFirstError;
const SkipPolicy = attrs.SkipPolicy || j$.NeverSkipPolicy;
this.skipPolicy_ = new SkipPolicy(this.queueableFns, this.firstCleanupIx);
this.errored = false;
if (typeof this.onComplete !== 'function') {
@@ -77,14 +79,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
this.run(0);
};
QueueRunner.prototype.skipToCleanup = function(lastRanIndex) {
if (lastRanIndex < this.firstCleanupIx) {
this.run(this.firstCleanupIx);
} else {
this.run(lastRanIndex + 1);
}
};
QueueRunner.prototype.clearTimeout = function(timeoutId) {
Function.prototype.apply.apply(this.timeout.clearTimeout, [
j$.getGlobal(),
@@ -125,11 +119,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}
function runNext() {
if (self.completeOnFirstError && errored) {
self.skipToCleanup(iterativeIndex);
} else {
self.run(iterativeIndex + 1);
}
self.run(self.nextFnIx_(iterativeIndex));
}
if (completedSynchronously) {
@@ -227,7 +217,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
for (
iterativeIndex = recursiveIndex;
iterativeIndex < length;
iterativeIndex++
iterativeIndex = this.nextFnIx_(iterativeIndex)
) {
var result = this.attempt(iterativeIndex);
@@ -236,11 +226,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}
self.errored = self.errored || result.errored;
if (this.completeOnFirstError && result.errored) {
this.skipToCleanup(iterativeIndex);
return;
}
}
this.clearStack(function() {
@@ -254,6 +239,16 @@ getJasmineRequireObj().QueueRunner = function(j$) {
});
};
QueueRunner.prototype.nextFnIx_ = function(currentFnIx) {
const result = this.skipPolicy_.skipTo(currentFnIx, this.errored);
if (result === currentFnIx) {
throw new Error("Can't skip to the same queueable fn that just finished");
}
return result;
};
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
var msg;

View File

@@ -60,6 +60,10 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
j$.MapContaining = jRequire.MapContaining(j$);
j$.SetContaining = jRequire.SetContaining(j$);
j$.QueueRunner = jRequire.QueueRunner(j$);
j$.NeverSkipPolicy = jRequire.NeverSkipPolicy(j$);
j$.CompleteOnFirstErrorSkipPolicy = jRequire.CompleteOnFirstErrorSkipPolicy(
j$
);
j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
j$.Spec = jRequire.Spec(j$);
j$.Spy = jRequire.Spy(j$);