Implement TreeProcessor to solve some issues with running the suite

- execute beforeAll/afterAll once per suite instead of once per child
  when running focused specs/suites Fixes #773
- refuse to execute an order if it would cause a suite with a beforeAll
  or afterAll to be re-entered after leaving once
- report children of an xdescribe similarly to how they would be
  reported if they were themselves x'd out Fixes #774
- only process the tree once instead of figuring it out again at each
  level

[finishes #87545620]
Fixes #776
This commit is contained in:
slackersoft
2015-02-27 11:16:53 -08:00
committed by Chris Amavisca and Gregg Van Hove
parent 0c68cc4afc
commit 715de7aa38
11 changed files with 1289 additions and 503 deletions

View File

@@ -4,18 +4,13 @@ getJasmineRequireObj().Suite = function() {
this.id = attrs.id;
this.parentSuite = attrs.parentSuite;
this.description = attrs.description;
this.onStart = attrs.onStart || function() {};
this.resultCallback = attrs.resultCallback || function() {};
this.clearStack = attrs.clearStack || function(fn) {fn();};
this.expectationFactory = attrs.expectationFactory;
this.expectationResultFactory = attrs.expectationResultFactory;
this.runnablesExplictlySetGetter = attrs.runnablesExplictlySetGetter || function() {};
this.beforeFns = [];
this.afterFns = [];
this.beforeAllFns = [];
this.afterAllFns = [];
this.queueRunner = attrs.queueRunner || function() {};
this.disabled = false;
this.children = [];
@@ -78,51 +73,17 @@ getJasmineRequireObj().Suite = function() {
}
};
Suite.prototype.execute = function(onComplete) {
var self = this;
this.onStart(this);
if (this.disabled) {
complete();
return;
}
var allFns = [];
for (var i = 0; i < this.children.length; i++) {
allFns.push(wrapChildAsAsync(this.children[i]));
}
if (this.isExecutable()) {
allFns = this.beforeAllFns.concat(allFns);
allFns = allFns.concat(this.afterAllFns);
}
this.queueRunner({
queueableFns: allFns,
onComplete: complete,
userContext: this.sharedUserContext(),
onException: function() { self.onException.apply(self, arguments); }
});
function complete() {
self.result.status = self.status();
self.resultCallback(self.result);
if (onComplete) {
onComplete();
}
}
function wrapChildAsAsync(child) {
return { fn: function(done) { child.execute(done); } };
}
Suite.prototype.isExecutable = function() {
return !this.disabled;
};
Suite.prototype.isExecutable = function() {
var runnablesExplicitlySet = this.runnablesExplictlySetGetter();
return !runnablesExplicitlySet && hasExecutableChild(this.children);
Suite.prototype.canBeReentered = function() {
return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;
};
Suite.prototype.getResult = function() {
this.result.status = this.status();
return this.result;
};
Suite.prototype.sharedUserContext = function() {
@@ -175,17 +136,6 @@ getJasmineRequireObj().Suite = function() {
return !args[0];
}
function hasExecutableChild(children) {
var foundActive = false;
for (var i = 0; i < children.length; i++) {
if (children[i].isExecutable()) {
foundActive = true;
break;
}
}
return foundActive;
}
function clone(obj) {
var clonedObj = {};
for (var prop in obj) {