Files
jasmine/spec/core/TreeProcessorSpec.js
2025-08-25 18:37:31 -07:00

318 lines
9.5 KiB
JavaScript

describe('TreeProcessor', function() {
let nodeNumber = 0,
leafNumber = 0;
function Node(attrs) {
attrs = attrs || {};
this.id = 'node' + nodeNumber++;
this.children = attrs.children || [];
this.canBeReentered = function() {
return !attrs.noReenter;
};
this.markedPending = attrs.markedPending || false;
this.sharedUserContext = function() {
return attrs.userContext || {};
};
this.getResult = jasmine.createSpy(this.id + '#execute');
this.beforeAllFns = attrs.beforeAllFns || [];
this.afterAllFns = attrs.afterAllFns || [];
this.cleanupBeforeAfter = function() {};
}
function Leaf(attrs) {
attrs = attrs || {};
this.id = 'leaf' + leafNumber++;
this.markedPending = attrs.markedPending || false;
this.execute = jasmine.createSpy(this.id + '#execute');
}
it('processes a single leaf', function() {
const leaf = new Leaf(),
processor = new jasmineUnderTest.TreeProcessor({
tree: leaf,
runnableIds: [leaf.id]
});
const result = processor.processTree();
expect(result.isExcluded(leaf)).toEqual(false);
});
it('processes a single pending leaf', function() {
const leaf = new Leaf({ markedPending: true }),
processor = new jasmineUnderTest.TreeProcessor({
tree: leaf,
runnableIds: [leaf.id]
});
const result = processor.processTree();
expect(result.isExcluded(leaf)).toEqual(false);
});
it('processes a single non-specified leaf', function() {
const leaf = new Leaf(),
processor = new jasmineUnderTest.TreeProcessor({
tree: leaf,
runnableIds: []
});
const result = processor.processTree();
expect(result.isExcluded(leaf)).toEqual(true);
});
it('processes a single excluded leaf', function() {
const leaf = new Leaf(),
processor = new jasmineUnderTest.TreeProcessor({
tree: leaf,
runnableIds: [leaf.id],
excludeNode: function() {
return true;
}
});
const result = processor.processTree();
expect(result.isExcluded(leaf)).toEqual(true);
});
it('processes a tree with a single leaf with the root specified', function() {
const leaf = new Leaf(),
parent = new Node({ children: [leaf] }),
processor = new jasmineUnderTest.TreeProcessor({
tree: parent,
runnableIds: [parent.id]
});
const result = processor.processTree();
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() {
const leaf = new Leaf({ markedPending: true }),
parent = new Node({ children: [leaf] }),
processor = new jasmineUnderTest.TreeProcessor({
tree: parent,
runnableIds: [parent.id]
});
const result = processor.processTree();
expect(result.isExcluded(parent)).toEqual(true);
expect(result.childrenOfTopSuite()).toEqual([{ spec: leaf }]);
expect(result.isExcluded(leaf)).toEqual(false);
});
it('runs orders leaves before non-specified leaves within a parent node', function() {
const specified = new Leaf();
const nonSpecified = new Leaf();
const root = new Node({ children: [nonSpecified, specified] });
const processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [specified.id]
});
const result = processor.processTree();
expect(result.childrenOfTopSuite()).toEqual([
{ spec: specified },
{ spec: nonSpecified }
]);
});
it('processes an excluded node with children', function() {
const leaf1 = new Leaf();
const node = new Node({ children: [leaf1] });
const root = new Node({ children: [node] });
const processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: []
});
const result = processor.processTree();
expect(result.childrenOfTopSuite()).toEqual([
{ suite: node, segmentNumber: 0 }
]);
expect(result.isExcluded(node)).toEqual(true);
expect(result.childrenOfSuiteSegment(node, 0)).toEqual([{ spec: leaf1 }]);
expect(result.isExcluded(node)).toEqual(true);
});
it('processes a complicated tree with the root specified', function() {
const pendingLeaf = new Leaf({ markedPending: true }),
executableLeaf = new Leaf({ markedPending: false }),
parent = new Node({ children: [pendingLeaf, executableLeaf] }),
childless = new Node(),
childOfPending = new Leaf({ markedPending: true }),
pendingNode = new Node({
markedPending: true,
children: [childOfPending]
}),
parentOfPendings = new Node({
markedPending: false,
children: [childless, pendingNode]
}),
root = new Node({ children: [parent, parentOfPendings] }),
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [root.id]
});
const result = processor.processTree();
expect(result.isExcluded(parent)).toEqual(false);
expect(result.childrenOfTopSuite()).toEqual([
{ suite: parent, segmentNumber: 0 },
{ suite: parentOfPendings, segmentNumber: 0 }
]);
expect(result.isExcluded(parentOfPendings)).toEqual(true);
expect(result.childrenOfSuiteSegment(parentOfPendings, 0)).toEqual([
{ suite: childless, segmentNumber: 0 },
{ suite: pendingNode, segmentNumber: 0 }
]);
expect(result.isExcluded(childless)).toEqual(true);
expect(result.childrenOfSuiteSegment(childless, 0)).toEqual([]);
expect(result.isExcluded(pendingLeaf)).toEqual(false);
expect(result.isExcluded(executableLeaf)).toEqual(false);
expect(result.isExcluded(parent)).toEqual(false);
expect(result.childrenOfSuiteSegment(parent, 0)).toEqual([
{ spec: pendingLeaf },
{ spec: executableLeaf }
]);
expect(result.isExcluded(pendingNode)).toEqual(true);
expect(result.childrenOfSuiteSegment(pendingNode, 0)).toEqual([
{ spec: childOfPending }
]);
expect(result.isExcluded(childOfPending)).toEqual(false);
});
it('throws if the specified order would re-enter a node that does not allow re-entry', function() {
const leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
reentered = new Node({ noReenter: true, children: [leaf1, leaf2] }),
root = new Node({ children: [reentered, leaf3] }),
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [leaf1.id, leaf3.id, leaf2.id]
});
expect(function() {
processor.processTree();
}).toThrowError(
'Invalid order: would cause a beforeAll or afterAll to be run multiple times'
);
});
it('does not throw if a node being re-entered allows re-entry', function() {
const leaf1 = new Leaf();
const leaf2 = new Leaf();
const leaf3 = new Leaf();
const reentered = new Node({ children: [leaf1, leaf2] });
const root = new Node({ children: [reentered, leaf3] });
const processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [leaf1.id, leaf3.id, leaf2.id]
});
const env = jasmineUnderTest.getEnv();
spyOn(env, 'deprecated');
processor.processTree();
expect(env.deprecated).toHaveBeenCalledWith(
'The specified spec/suite order splits up a suite, running unrelated specs in the middle of it. This will become an error in a future release.'
);
});
it("does not throw if a node which can't be re-entered is only entered once", function() {
const leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
noReentry = new Node({ noReenter: true }),
root = new Node({ children: [noReentry] }),
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [leaf2.id, leaf1.id, leaf3.id]
});
processor.processTree();
});
it("does not throw if a node which can't be re-entered is run directly", function() {
const noReentry = new Node({ noReenter: true }),
root = new Node({ children: [noReentry] }),
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [root.id]
});
processor.processTree();
});
it('orders children according to orderChildren when specified', function() {
const leaf1 = new Leaf();
const leaf2 = new Leaf();
const leaf3 = new Leaf();
const leaf4 = new Leaf();
const leaf5 = new Leaf();
const leaf6 = new Leaf();
const leaf7 = new Leaf();
const leaf8 = new Leaf();
const leaf9 = new Leaf();
const leaf10 = new Leaf();
const leaf11 = new Leaf();
const root = new Node({
children: [
leaf1,
leaf2,
leaf3,
leaf4,
leaf5,
leaf6,
leaf7,
leaf8,
leaf9,
leaf10,
leaf11
]
});
const runQueue = jasmine.createSpy('runQueue');
const processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [root.id],
runQueue,
orderChildren: function(node) {
const children = node.children.slice();
return children.reverse();
}
});
const result = processor.processTree();
expect(result.childrenOfTopSuite()).toEqual([
{ spec: leaf11 },
{ spec: leaf10 },
{ spec: leaf9 },
{ spec: leaf8 },
{ spec: leaf7 },
{ spec: leaf6 },
{ spec: leaf5 },
{ spec: leaf4 },
{ spec: leaf3 },
{ spec: leaf2 },
{ spec: leaf1 }
]);
});
});