diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index e1b2ca6d..70298560 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -9407,7 +9407,7 @@ getJasmineRequireObj().Runner = function(j$) { #runableResources; #runQueue; #TreeProcessor; - #treeProcessor; + #executionTree; #globalErrors; #reportDispatcher; #getConfig; @@ -9470,7 +9470,7 @@ getJasmineRequireObj().Runner = function(j$) { seed: j$.isNumber_(config.seed) ? config.seed + '' : config.seed }); - this.#treeProcessor = new this.#TreeProcessor({ + const treeProcessor = new this.#TreeProcessor({ tree: this.#topSuite, runnableIds: runablesToRun, orderChildren: function(node) { @@ -9480,7 +9480,7 @@ getJasmineRequireObj().Runner = function(j$) { return !config.specFilter(spec); } }); - this.#treeProcessor.processTree(); + this.#executionTree = treeProcessor.processTree(); return this.#execute2(runablesToRun, order); } @@ -9565,7 +9565,7 @@ getJasmineRequireObj().Runner = function(j$) { async #executeTopSuite() { const wrappedChildren = this.#wrapNodes( - this.#treeProcessor.childrenOfTopSuite() + this.#executionTree.childrenOfTopSuite() ); const queueableFns = this.#addBeforeAndAfterAlls( this.#topSuite, @@ -9589,7 +9589,7 @@ getJasmineRequireObj().Runner = function(j$) { #executeSuiteSegment(suite, segmentNumber, done) { const wrappedChildren = this.#wrapNodes( - this.#treeProcessor.childrenOfSuiteSegment(suite, segmentNumber) + this.#executionTree.childrenOfSuiteSegment(suite, segmentNumber) ); const onStart = { fn: next => { @@ -9627,7 +9627,7 @@ getJasmineRequireObj().Runner = function(j$) { this.#runQueueWithSkipPolicy.bind(this), this.#globalErrors, done, - this.#treeProcessor.isExcluded(spec), + this.#executionTree.isExcluded(spec), config.failSpecWithNoExpectations, config.detectLateRejectionHandling ); @@ -9648,7 +9648,7 @@ getJasmineRequireObj().Runner = function(j$) { } #addBeforeAndAfterAlls(suite, wrappedChildren) { - if (this.#treeProcessor.isExcluded(suite)) { + if (this.#executionTree.isExcluded(suite)) { return wrappedChildren; } @@ -11401,13 +11401,15 @@ getJasmineRequireObj().TreeProcessor = function(j$) { const defaultMin = Infinity; const defaultMax = 1 - Infinity; + // Transforms the suite tree into an execution tree, which represents the set + // of specs and (possibly interleaved) suites to be run in the order they are + // to be run in. class TreeProcessor { #tree; #runnableIds; #orderChildren; #excludeNode; #stats; - #processed; constructor(attrs) { this.#tree = attrs.tree; @@ -11423,34 +11425,14 @@ getJasmineRequireObj().TreeProcessor = function(j$) { function(node) { return false; }; - this.#stats = {}; - this.#processed = false; } processTree() { + this.#stats = {}; this.#processNode(this.#tree, true); - this.#processed = true; - } - - childrenOfTopSuite() { - return this.childrenOfSuiteSegment(this.#tree, 0); - } - - childrenOfSuiteSegment(suite, segmentNumber) { - const segmentChildren = this.#stats[suite.id].segments[segmentNumber] - .nodes; - return segmentChildren.map(function(child) { - if (child.owner.children) { - return { suite: child.owner, segmentNumber: child.index }; - } else { - return { spec: child.owner }; - } - }); - } - - isExcluded(node) { - const nodeStats = this.#stats[node.id]; - return node.children ? !nodeStats.willExecute : nodeStats.excluded; + const result = new ExecutionTree(this.#tree, this.#stats); + this.#stats = null; + return result; } #runnableIndex(id) { @@ -11517,6 +11499,37 @@ getJasmineRequireObj().TreeProcessor = function(j$) { } } + class ExecutionTree { + #topSuite; + #stats; + + constructor(topSuite, stats) { + this.#topSuite = topSuite; + this.#stats = stats; + } + + childrenOfTopSuite() { + return this.childrenOfSuiteSegment(this.#topSuite, 0); + } + + childrenOfSuiteSegment(suite, segmentNumber) { + const segmentChildren = this.#stats[suite.id].segments[segmentNumber] + .nodes; + return segmentChildren.map(function(child) { + if (child.owner.children) { + return { suite: child.owner, segmentNumber: child.index }; + } else { + return { spec: child.owner }; + } + }); + } + + isExcluded(node) { + const nodeStats = this.#stats[node.id]; + return node.children ? !nodeStats.willExecute : nodeStats.excluded; + } + } + function segmentChildren(node, orderedChildren, stats, executableIndex) { let currentSegment = { index: 0, diff --git a/spec/core/TreeProcessorSpec.js b/spec/core/TreeProcessorSpec.js index b9e37537..478478af 100644 --- a/spec/core/TreeProcessorSpec.js +++ b/spec/core/TreeProcessorSpec.js @@ -33,9 +33,9 @@ describe('TreeProcessor', function() { runnableIds: [leaf.id] }); - processor.processTree(); + const result = processor.processTree(); - expect(processor.isExcluded(leaf)).toEqual(false); + expect(result.isExcluded(leaf)).toEqual(false); }); it('processes a single pending leaf', function() { @@ -45,9 +45,9 @@ describe('TreeProcessor', function() { runnableIds: [leaf.id] }); - processor.processTree(); + const result = processor.processTree(); - expect(processor.isExcluded(leaf)).toEqual(false); + expect(result.isExcluded(leaf)).toEqual(false); }); it('processes a single non-specified leaf', function() { @@ -57,9 +57,9 @@ describe('TreeProcessor', function() { runnableIds: [] }); - processor.processTree(); + const result = processor.processTree(); - expect(processor.isExcluded(leaf)).toEqual(true); + expect(result.isExcluded(leaf)).toEqual(true); }); it('processes a single excluded leaf', function() { @@ -72,9 +72,9 @@ describe('TreeProcessor', function() { } }); - processor.processTree(); + const result = processor.processTree(); - expect(processor.isExcluded(leaf)).toEqual(true); + expect(result.isExcluded(leaf)).toEqual(true); }); it('processes a tree with a single leaf with the root specified', function() { @@ -85,11 +85,11 @@ describe('TreeProcessor', function() { runnableIds: [parent.id] }); - processor.processTree(); + const result = processor.processTree(); - expect(processor.isExcluded(parent)).toEqual(false); - expect(processor.childrenOfTopSuite()).toEqual([{ spec: leaf }]); - expect(processor.isExcluded(leaf)).toEqual(false); + expect(result.isExcluded(parent)).toEqual(false); + expect(result.childrenOfTopSuite()).toEqual([{ spec: leaf }]); + expect(result.isExcluded(leaf)).toEqual(false); }); it('processes a tree with a single pending leaf, with the root specified', function() { @@ -100,11 +100,11 @@ describe('TreeProcessor', function() { runnableIds: [parent.id] }); - processor.processTree(); + const result = processor.processTree(); - expect(processor.isExcluded(parent)).toEqual(true); - expect(processor.childrenOfTopSuite()).toEqual([{ spec: leaf }]); - expect(processor.isExcluded(leaf)).toEqual(false); + expect(result.isExcluded(parent)).toEqual(true); + expect(result.childrenOfTopSuite()).toEqual([{ spec: leaf }]); + expect(result.isExcluded(leaf)).toEqual(false); }); it('processes a complicated tree with the root specified', function() { @@ -127,38 +127,38 @@ describe('TreeProcessor', function() { runnableIds: [root.id] }); - processor.processTree(); + const result = processor.processTree(); - expect(processor.isExcluded(parent)).toEqual(false); - expect(processor.childrenOfTopSuite()).toEqual([ + expect(result.isExcluded(parent)).toEqual(false); + expect(result.childrenOfTopSuite()).toEqual([ { suite: parent, segmentNumber: 0 }, { suite: parentOfPendings, segmentNumber: 0 } ]); - expect(processor.isExcluded(parentOfPendings)).toEqual(true); - expect(processor.childrenOfSuiteSegment(parentOfPendings, 0)).toEqual([ + expect(result.isExcluded(parentOfPendings)).toEqual(true); + expect(result.childrenOfSuiteSegment(parentOfPendings, 0)).toEqual([ { suite: childless, segmentNumber: 0 }, { suite: pendingNode, segmentNumber: 0 } ]); - expect(processor.isExcluded(childless)).toEqual(true); - expect(processor.childrenOfSuiteSegment(childless, 0)).toEqual([]); + expect(result.isExcluded(childless)).toEqual(true); + expect(result.childrenOfSuiteSegment(childless, 0)).toEqual([]); - expect(processor.isExcluded(pendingLeaf)).toEqual(false); - expect(processor.isExcluded(executableLeaf)).toEqual(false); + expect(result.isExcluded(pendingLeaf)).toEqual(false); + expect(result.isExcluded(executableLeaf)).toEqual(false); - expect(processor.isExcluded(parent)).toEqual(false); - expect(processor.childrenOfSuiteSegment(parent, 0)).toEqual([ + expect(result.isExcluded(parent)).toEqual(false); + expect(result.childrenOfSuiteSegment(parent, 0)).toEqual([ { spec: pendingLeaf }, { spec: executableLeaf } ]); - expect(processor.isExcluded(pendingNode)).toEqual(true); - expect(processor.childrenOfSuiteSegment(pendingNode, 0)).toEqual([ + expect(result.isExcluded(pendingNode)).toEqual(true); + expect(result.childrenOfSuiteSegment(pendingNode, 0)).toEqual([ { spec: childOfPending } ]); - expect(processor.isExcluded(childOfPending)).toEqual(false); + expect(result.isExcluded(childOfPending)).toEqual(false); }); it('throws if the specified order would re-enter a node that does not allow re-entry', function() { diff --git a/src/core/Runner.js b/src/core/Runner.js index 0abfc143..fdf70755 100644 --- a/src/core/Runner.js +++ b/src/core/Runner.js @@ -6,7 +6,7 @@ getJasmineRequireObj().Runner = function(j$) { #runableResources; #runQueue; #TreeProcessor; - #treeProcessor; + #executionTree; #globalErrors; #reportDispatcher; #getConfig; @@ -69,7 +69,7 @@ getJasmineRequireObj().Runner = function(j$) { seed: j$.isNumber_(config.seed) ? config.seed + '' : config.seed }); - this.#treeProcessor = new this.#TreeProcessor({ + const treeProcessor = new this.#TreeProcessor({ tree: this.#topSuite, runnableIds: runablesToRun, orderChildren: function(node) { @@ -79,7 +79,7 @@ getJasmineRequireObj().Runner = function(j$) { return !config.specFilter(spec); } }); - this.#treeProcessor.processTree(); + this.#executionTree = treeProcessor.processTree(); return this.#execute2(runablesToRun, order); } @@ -164,7 +164,7 @@ getJasmineRequireObj().Runner = function(j$) { async #executeTopSuite() { const wrappedChildren = this.#wrapNodes( - this.#treeProcessor.childrenOfTopSuite() + this.#executionTree.childrenOfTopSuite() ); const queueableFns = this.#addBeforeAndAfterAlls( this.#topSuite, @@ -188,7 +188,7 @@ getJasmineRequireObj().Runner = function(j$) { #executeSuiteSegment(suite, segmentNumber, done) { const wrappedChildren = this.#wrapNodes( - this.#treeProcessor.childrenOfSuiteSegment(suite, segmentNumber) + this.#executionTree.childrenOfSuiteSegment(suite, segmentNumber) ); const onStart = { fn: next => { @@ -226,7 +226,7 @@ getJasmineRequireObj().Runner = function(j$) { this.#runQueueWithSkipPolicy.bind(this), this.#globalErrors, done, - this.#treeProcessor.isExcluded(spec), + this.#executionTree.isExcluded(spec), config.failSpecWithNoExpectations, config.detectLateRejectionHandling ); @@ -247,7 +247,7 @@ getJasmineRequireObj().Runner = function(j$) { } #addBeforeAndAfterAlls(suite, wrappedChildren) { - if (this.#treeProcessor.isExcluded(suite)) { + if (this.#executionTree.isExcluded(suite)) { return wrappedChildren; } diff --git a/src/core/TreeProcessor.js b/src/core/TreeProcessor.js index 8107c7ee..ff3dba4d 100644 --- a/src/core/TreeProcessor.js +++ b/src/core/TreeProcessor.js @@ -2,13 +2,15 @@ getJasmineRequireObj().TreeProcessor = function(j$) { const defaultMin = Infinity; const defaultMax = 1 - Infinity; + // Transforms the suite tree into an execution tree, which represents the set + // of specs and (possibly interleaved) suites to be run in the order they are + // to be run in. class TreeProcessor { #tree; #runnableIds; #orderChildren; #excludeNode; #stats; - #processed; constructor(attrs) { this.#tree = attrs.tree; @@ -24,34 +26,14 @@ getJasmineRequireObj().TreeProcessor = function(j$) { function(node) { return false; }; - this.#stats = {}; - this.#processed = false; } processTree() { + this.#stats = {}; this.#processNode(this.#tree, true); - this.#processed = true; - } - - childrenOfTopSuite() { - return this.childrenOfSuiteSegment(this.#tree, 0); - } - - childrenOfSuiteSegment(suite, segmentNumber) { - const segmentChildren = this.#stats[suite.id].segments[segmentNumber] - .nodes; - return segmentChildren.map(function(child) { - if (child.owner.children) { - return { suite: child.owner, segmentNumber: child.index }; - } else { - return { spec: child.owner }; - } - }); - } - - isExcluded(node) { - const nodeStats = this.#stats[node.id]; - return node.children ? !nodeStats.willExecute : nodeStats.excluded; + const result = new ExecutionTree(this.#tree, this.#stats); + this.#stats = null; + return result; } #runnableIndex(id) { @@ -118,6 +100,37 @@ getJasmineRequireObj().TreeProcessor = function(j$) { } } + class ExecutionTree { + #topSuite; + #stats; + + constructor(topSuite, stats) { + this.#topSuite = topSuite; + this.#stats = stats; + } + + childrenOfTopSuite() { + return this.childrenOfSuiteSegment(this.#topSuite, 0); + } + + childrenOfSuiteSegment(suite, segmentNumber) { + const segmentChildren = this.#stats[suite.id].segments[segmentNumber] + .nodes; + return segmentChildren.map(function(child) { + if (child.owner.children) { + return { suite: child.owner, segmentNumber: child.index }; + } else { + return { spec: child.owner }; + } + }); + } + + isExcluded(node) { + const nodeStats = this.#stats[node.id]; + return node.children ? !nodeStats.willExecute : nodeStats.excluded; + } + } + function segmentChildren(node, orderedChildren, stats, executableIndex) { let currentSegment = { index: 0,