Move beforeAll failure reporting into TreeRunner

This commit is contained in:
Steve Gravrock
2025-08-30 07:42:29 -07:00
parent 4b7d5e3623
commit 50e566bd67
4 changed files with 79 additions and 104 deletions

View File

@@ -9472,17 +9472,10 @@ getJasmineRequireObj().Runner = function(j$) {
reportDispatcher: this.#reportDispatcher,
runQueue: this.#runQueue,
getConfig: this.#getConfig,
reportChildrenOfBeforeAllFailure: this.#reportChildrenOfBeforeAllFailure.bind(
this
),
currentRunableTracker: this.#currentRunableTracker
});
const { hasFailures } = await treeRunner.execute();
if (this.#topSuite.hadBeforeAllFailure) {
await this.#reportChildrenOfBeforeAllFailure(this.#topSuite);
}
this.#runableResources.clearForRunable(this.#topSuite.id);
this.#currentRunableTracker.popSuite();
let overallStatus, incompleteReason, incompleteCode;
@@ -9527,47 +9520,6 @@ getJasmineRequireObj().Runner = function(j$) {
await this.#reportDispatcher.jasmineDone(jasmineDoneInfo);
return jasmineDoneInfo;
}
// TODO: de-duplicate w/TreeRunner
#reportSpecDone(spec, result, next) {
spec.reportedDone = true;
this.#reportDispatcher.specDone(result).then(next);
}
async #reportChildrenOfBeforeAllFailure(suite) {
for (const child of suite.children) {
if (child instanceof j$.Suite) {
await this.#reportDispatcher.suiteStarted(child.result);
await this.#reportChildrenOfBeforeAllFailure(child);
// Marking the suite passed is consistent with how suites that
// contain failed specs but no suite-level failures are reported.
child.result.status = 'passed';
await this.#reportDispatcher.suiteDone(child.result);
} else {
/* a spec */
await this.#reportDispatcher.specStarted(child.result);
child.addExpectationResult(
false,
{
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
},
true
);
child.result.status = 'failed';
await new Promise(resolve => {
this.#reportSpecDone(child, child.result, resolve);
});
}
}
}
}
return Runner;
@@ -11442,7 +11394,6 @@ getJasmineRequireObj().TreeRunner = function(j$) {
#reportDispatcher;
#runQueue;
#getConfig;
#reportChildrenOfBeforeAllFailure;
#currentRunableTracker;
#hasFailures;
@@ -11454,8 +11405,6 @@ getJasmineRequireObj().TreeRunner = function(j$) {
this.#reportDispatcher = attrs.reportDispatcher;
this.#runQueue = attrs.runQueue;
this.#getConfig = attrs.getConfig;
this.#reportChildrenOfBeforeAllFailure =
attrs.reportChildrenOfBeforeAllFailure;
this.#currentRunableTracker = attrs.currentRunableTracker;
}
@@ -11485,6 +11434,10 @@ getJasmineRequireObj().TreeRunner = function(j$) {
});
});
if (topSuite.hadBeforeAllFailure) {
await this.#reportChildrenOfBeforeAllFailure(topSuite);
}
return { hasFailures: this.#hasFailures };
}
@@ -11682,6 +11635,38 @@ getJasmineRequireObj().TreeRunner = function(j$) {
await this.#reportDispatcher.specDone(spec.result);
}
async #reportChildrenOfBeforeAllFailure(suite) {
for (const child of suite.children) {
if (child instanceof j$.Suite) {
await this.#reportDispatcher.suiteStarted(child.result);
await this.#reportChildrenOfBeforeAllFailure(child);
// Marking the suite passed is consistent with how suites that
// contain failed specs but no suite-level failures are reported.
child.result.status = 'passed';
await this.#reportDispatcher.suiteDone(child.result);
} else {
/* a spec */
await this.#reportDispatcher.specStarted(child.result);
child.addExpectationResult(
false,
{
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
},
true
);
child.result.status = 'failed';
await this.#reportSpecDone(child);
}
}
}
#addBeforeAndAfterAlls(suite, wrappedChildren) {
if (this.#executionTree.isExcluded(suite)) {
return wrappedChildren;

View File

@@ -406,6 +406,8 @@ describe('TreeRunner', function() {
parentSuite: suite,
queueableFn: { fn() {} }
});
suite.addChild(spec);
topSuite.addChild(suite);
const executionTree = {
topSuite,
childrenOfTopSuite() {
@@ -447,9 +449,12 @@ describe('TreeRunner', function() {
suiteRunQueueOpts.queueableFns[0].fn();
suite.hadBeforeAllFailure = true;
suiteRunQueueOpts.onComplete();
await Promise.resolve();
expect(reportChildrenOfBeforeAllFailure).toHaveBeenCalledBefore(
while (reportDispatcher.suiteDone.calls.count() === 0) {
await Promise.resolve();
}
expect(reportDispatcher.specDone).toHaveBeenCalledBefore(
reportDispatcher.suiteDone
);
await expectAsync(executePromise).toBePending();

View File

@@ -115,17 +115,10 @@ getJasmineRequireObj().Runner = function(j$) {
reportDispatcher: this.#reportDispatcher,
runQueue: this.#runQueue,
getConfig: this.#getConfig,
reportChildrenOfBeforeAllFailure: this.#reportChildrenOfBeforeAllFailure.bind(
this
),
currentRunableTracker: this.#currentRunableTracker
});
const { hasFailures } = await treeRunner.execute();
if (this.#topSuite.hadBeforeAllFailure) {
await this.#reportChildrenOfBeforeAllFailure(this.#topSuite);
}
this.#runableResources.clearForRunable(this.#topSuite.id);
this.#currentRunableTracker.popSuite();
let overallStatus, incompleteReason, incompleteCode;
@@ -170,47 +163,6 @@ getJasmineRequireObj().Runner = function(j$) {
await this.#reportDispatcher.jasmineDone(jasmineDoneInfo);
return jasmineDoneInfo;
}
// TODO: de-duplicate w/TreeRunner
#reportSpecDone(spec, result, next) {
spec.reportedDone = true;
this.#reportDispatcher.specDone(result).then(next);
}
async #reportChildrenOfBeforeAllFailure(suite) {
for (const child of suite.children) {
if (child instanceof j$.Suite) {
await this.#reportDispatcher.suiteStarted(child.result);
await this.#reportChildrenOfBeforeAllFailure(child);
// Marking the suite passed is consistent with how suites that
// contain failed specs but no suite-level failures are reported.
child.result.status = 'passed';
await this.#reportDispatcher.suiteDone(child.result);
} else {
/* a spec */
await this.#reportDispatcher.specStarted(child.result);
child.addExpectationResult(
false,
{
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
},
true
);
child.result.status = 'failed';
await new Promise(resolve => {
this.#reportSpecDone(child, child.result, resolve);
});
}
}
}
}
return Runner;

View File

@@ -7,7 +7,6 @@ getJasmineRequireObj().TreeRunner = function(j$) {
#reportDispatcher;
#runQueue;
#getConfig;
#reportChildrenOfBeforeAllFailure;
#currentRunableTracker;
#hasFailures;
@@ -19,8 +18,6 @@ getJasmineRequireObj().TreeRunner = function(j$) {
this.#reportDispatcher = attrs.reportDispatcher;
this.#runQueue = attrs.runQueue;
this.#getConfig = attrs.getConfig;
this.#reportChildrenOfBeforeAllFailure =
attrs.reportChildrenOfBeforeAllFailure;
this.#currentRunableTracker = attrs.currentRunableTracker;
}
@@ -50,6 +47,10 @@ getJasmineRequireObj().TreeRunner = function(j$) {
});
});
if (topSuite.hadBeforeAllFailure) {
await this.#reportChildrenOfBeforeAllFailure(topSuite);
}
return { hasFailures: this.#hasFailures };
}
@@ -247,6 +248,38 @@ getJasmineRequireObj().TreeRunner = function(j$) {
await this.#reportDispatcher.specDone(spec.result);
}
async #reportChildrenOfBeforeAllFailure(suite) {
for (const child of suite.children) {
if (child instanceof j$.Suite) {
await this.#reportDispatcher.suiteStarted(child.result);
await this.#reportChildrenOfBeforeAllFailure(child);
// Marking the suite passed is consistent with how suites that
// contain failed specs but no suite-level failures are reported.
child.result.status = 'passed';
await this.#reportDispatcher.suiteDone(child.result);
} else {
/* a spec */
await this.#reportDispatcher.specStarted(child.result);
child.addExpectationResult(
false,
{
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
},
true
);
child.result.status = 'failed';
await this.#reportSpecDone(child);
}
}
}
#addBeforeAndAfterAlls(suite, wrappedChildren) {
if (this.#executionTree.isExcluded(suite)) {
return wrappedChildren;