Suites report errors in afterAlls in the suiteDone event

- remove `afterAllEvent` from reporters
This commit is contained in:
slackersoft
2014-09-03 18:52:13 -07:00
parent 6b857d11ce
commit 9402d59859
14 changed files with 306 additions and 203 deletions

View File

@@ -55,7 +55,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
yellow: '\x1B[33m',
none: '\x1B[0m'
},
exceptionList = [];
failedSuites = [];
this.jasmineStarted = function() {
specCount = 0;
@@ -87,12 +87,8 @@ getJasmineRequireObj().ConsoleReporter = function() {
print('Finished in ' + seconds + ' ' + plural('second', seconds));
printNewline();
for(i = 0; i < exceptionList.length; i++) {
printNewline();
print(colored('red', 'An error was thrown in an afterAll'));
printNewline();
print(colored('red', (exceptionList[i].message || exceptionList[i].description)));
printNewline();
for(i = 0; i < failedSuites.length; i++) {
suiteFailureDetails(failedSuites[i]);
}
onComplete(failureCount === 0);
@@ -119,8 +115,11 @@ getJasmineRequireObj().ConsoleReporter = function() {
}
};
this.afterAllError = function(error) {
exceptionList.push(error);
this.suiteDone = function(result) {
if (result.failedExpectations && result.failedExpectations.length > 0) {
failureCount++;
failedSuites.push(result);
}
};
return this;
@@ -166,6 +165,17 @@ getJasmineRequireObj().ConsoleReporter = function() {
printNewline();
}
function suiteFailureDetails(result) {
for (var i = 0; i < result.failedExpectations.length; i++) {
printNewline();
print(colored('red', 'An error was thrown in an afterAll'));
printNewline();
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
}
printNewline();
}
}
return ConsoleReporter;

View File

@@ -47,7 +47,7 @@ jasmineRequire.HtmlReporter = function(j$) {
pendingSpecCount = 0,
htmlReporterMain,
symbols,
exceptionList = [];
failedSuites = [];
this.initialize = function() {
htmlReporterMain = createDom('div', {className: 'html-reporter'},
@@ -83,6 +83,10 @@ jasmineRequire.HtmlReporter = function(j$) {
};
this.suiteDone = function(result) {
if (result.failedExpectations && result.failedExpectations.length > 0) {
failedSuites.push(result);
}
if (currentParent == topResults) {
return;
}
@@ -94,10 +98,6 @@ jasmineRequire.HtmlReporter = function(j$) {
currentParent.addChild(result, 'spec');
};
this.afterAllException = function(error) {
exceptionList.push(error);
};
var failures = [];
this.specDone = function(result) {
if (result.status != 'disabled') {
@@ -170,10 +170,13 @@ jasmineRequire.HtmlReporter = function(j$) {
var statusBarClassName = 'bar ' + ((failureCount > 0) ? 'failed' : 'passed');
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
for(i = 0; i < exceptionList.length; i++) {
var errorBarMessage = 'An error was thrown in an afterAll: ' + (exceptionList[i].message || exceptionList[i].description);
var errorBarClassName = 'bar errored';
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
for(i = 0; i < failedSuites.length; i++) {
var failedSuite = failedSuites[i];
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
var errorBarClassName = 'bar errored';
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
}
}
var results = find('.results');

View File

@@ -250,11 +250,9 @@ getJasmineRequireObj().Spec = function(j$) {
this.id = attrs.id;
this.description = attrs.description || '';
this.queueableFn = attrs.queueableFn;
this.beforeFns = attrs.beforeFns || function() { return []; };
this.afterFns = attrs.afterFns || function() { return []; };
this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; };
this.userContext = attrs.userContext || function() { return {}; };
this.onStart = attrs.onStart || function() {};
this.exceptionFormatter = attrs.exceptionFormatter || function() {};
this.getSpecName = attrs.getSpecName || function() { return ''; };
this.expectationResultFactory = attrs.expectationResultFactory || function() { };
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
@@ -293,7 +291,8 @@ getJasmineRequireObj().Spec = function(j$) {
return;
}
var allFns = this.beforeFns().concat(this.queueableFn).concat(this.afterFns());
var fns = this.beforeAndAfterFns();
var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters);
this.queueRunnerFactory({
queueableFns: allFns,
@@ -408,8 +407,7 @@ getJasmineRequireObj().Env = function(j$) {
'suiteStarted',
'suiteDone',
'specStarted',
'specDone',
'afterAllException'
'specDone'
]);
this.specFilter = function() {
@@ -475,25 +473,28 @@ getJasmineRequireObj().Env = function(j$) {
delete runnableResources[id];
};
var beforeFns = function(suite) {
var beforeAndAfterFns = function(suite, runnablesExplictlySet) {
return function() {
var befores = [];
var befores = [],
afters = [],
beforeAlls = [],
afterAlls = [];
while(suite) {
befores = befores.concat(suite.beforeFns);
suite = suite.parentSuite;
}
return befores.reverse();
};
};
var afterFns = function(suite) {
return function() {
var afters = [];
while(suite) {
afters = afters.concat(suite.afterFns);
if (runnablesExplictlySet()) {
beforeAlls = beforeAlls.concat(suite.beforeAllFns);
afterAlls = afterAlls.concat(suite.afterAllFns);
}
suite = suite.parentSuite;
}
return afters;
return {
befores: beforeAlls.reverse().concat(befores.reverse()),
afters: afters.concat(afterAlls)
};
};
};
@@ -540,7 +541,6 @@ getJasmineRequireObj().Env = function(j$) {
var queueRunnerFactory = function(options) {
options.catchException = catchException;
options.reporter = reporter;
options.clearStack = options.clearStack || clearStack;
options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
@@ -552,7 +552,9 @@ getJasmineRequireObj().Env = function(j$) {
id: getNextSuiteId(),
description: 'Jasmine__TopLevel__Suite',
queueRunner: queueRunnerFactory,
resultCallback: function() {} // TODO - hook this up
resultCallback: function(attrs) {
reporter.suiteDone(attrs);
}
});
runnableLookupTable[topSuite.id] = topSuite;
defaultResourcesForRunnable(topSuite.id);
@@ -563,7 +565,14 @@ getJasmineRequireObj().Env = function(j$) {
};
this.execute = function(runnablesToRun) {
runnablesToRun = runnablesToRun || [topSuite.id];
if(runnablesToRun) {
runnablesExplictlySet = true;
} else if (focusedRunnables.length) {
runnablesExplictlySet = true;
runnablesToRun = focusedRunnables;
} else {
runnablesToRun = [topSuite.id];
}
var allFns = [];
for(var i = 0; i < runnablesToRun.length; i++) {
@@ -602,6 +611,7 @@ getJasmineRequireObj().Env = function(j$) {
queueRunner: queueRunnerFactory,
onStart: suiteStarted,
expectationFactory: expectationFactory,
expectationResultFactory: expectationResultFactory,
resultCallback: function(attrs) {
if (!suite.disabled) {
clearResourcesForRunnable(suite.id);
@@ -623,7 +633,28 @@ getJasmineRequireObj().Env = function(j$) {
this.describe = function(description, specDefinitions) {
var suite = suiteFactory(description);
addSpecsToSuite(suite, specDefinitions);
return suite;
};
this.xdescribe = function(description, specDefinitions) {
var suite = this.describe(description, specDefinitions);
suite.disable();
return suite;
};
this.fdescribe = function(description, specDefinitions) {
var suite = suiteFactory(description);
suite.isFocused = true;
addSpecsToSuite(suite, specDefinitions);
if (!hasFocusedAncestor(suite.parentSuite)) {
focusedRunnables.push(suite.id);
}
return suite;
};
function addSpecsToSuite(suite, specDefinitions) {
var parentSuite = currentDeclarationSuite;
parentSuite.addChild(suite);
currentDeclarationSuite = suite;
@@ -636,31 +667,37 @@ getJasmineRequireObj().Env = function(j$) {
}
if (declarationError) {
this.it('encountered a declaration exception', function() {
self.it('encountered a declaration exception', function() {
throw declarationError;
});
}
currentDeclarationSuite = parentSuite;
}
return suite;
};
function hasFocusedAncestor(suite) {
while (suite) {
if (suite.isFocused) {
return true;
}
suite = suite.parentSuite;
}
this.xdescribe = function(description, specDefinitions) {
var suite = this.describe(description, specDefinitions);
suite.disable();
return suite;
return false;
}
var runnablesExplictlySet = false;
var runnablesExplictlySetGetter = function(){
return runnablesExplictlySet;
};
var specFactory = function(description, fn, suite) {
totalSpecsDefined++;
var spec = new j$.Spec({
id: getNextSpecId(),
beforeFns: beforeFns(suite),
afterFns: afterFns(suite),
beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter),
expectationFactory: expectationFactory,
exceptionFormatter: exceptionFormatter,
resultCallback: specResultCallback,
getSpecName: function(spec) {
return getSpecName(spec, suite);
@@ -670,7 +707,7 @@ getJasmineRequireObj().Env = function(j$) {
expectationResultFactory: expectationResultFactory,
queueRunnerFactory: queueRunnerFactory,
userContext: function() { return suite.clonedSharedUserContext(); },
queueableFn: { fn: fn, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } }
queueableFn: { fn: fn, type: 'it', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } }
});
runnableLookupTable[spec.id] = spec;
@@ -706,24 +743,35 @@ getJasmineRequireObj().Env = function(j$) {
return spec;
};
var focusedRunnables = [];
this.fit = function(description, fn ){
var spec = this.it(description, fn);
if (!hasFocusedAncestor(currentDeclarationSuite)) {
focusedRunnables.push(spec.id);
}
return spec;
};
this.expect = function(actual) {
return currentRunnable().expect(actual);
};
this.beforeEach = function(beforeEachFunction) {
currentDeclarationSuite.beforeEach({ fn: beforeEachFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.beforeEach({ fn: beforeEachFunction, type: 'beforeEach', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.beforeAll = function(beforeAllFunction) {
currentDeclarationSuite.beforeAll({ fn: beforeAllFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.beforeAll({ fn: beforeAllFunction, type: 'beforeAll', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.afterEach = function(afterEachFunction) {
currentDeclarationSuite.afterEach({ fn: afterEachFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.afterEach({ fn: afterEachFunction, type: 'afterEach', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.afterAll = function(afterAllFunction) {
currentDeclarationSuite.afterAll({ fn: afterAllFunction, isAfterAll: true, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.afterAll({ fn: afterAllFunction, type: 'afterAll', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.pending = function() {
@@ -1583,7 +1631,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
this.catchException = attrs.catchException || function() { return true; };
this.userContext = attrs.userContext || {};
this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
this.reporter = attrs.reporter;
}
QueueRunner.prototype.execute = function() {
@@ -1591,10 +1638,10 @@ getJasmineRequireObj().QueueRunner = function(j$) {
};
QueueRunner.prototype.run = function(queueableFns, recursiveIndex) {
var runner = this,
length = queueableFns.length,
self = this,
iterativeIndex;
var length = queueableFns.length,
self = this,
iterativeIndex;
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
var queueableFn = queueableFns[iterativeIndex];
@@ -1615,10 +1662,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
queueableFn.fn.call(self.userContext);
} catch (e) {
if(queueableFn.isAfterAll){
runner.reporter.afterAllException(e);
}
handleException(e);
handleException(e, queueableFn);
}
}
@@ -1634,7 +1678,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
if (queueableFn.timeout) {
timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
self.onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
onException(error, queueableFn);
next();
}, queueableFn.timeout()]]);
}
@@ -1642,16 +1687,17 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
queueableFn.fn.call(self.userContext, next);
} catch (e) {
if(queueableFn.isAfterAll) {
runner.reporter.afterAllException(e);
}
handleException(e);
handleException(e, queueableFn);
next();
}
}
function handleException(e) {
function onException(e, queueableFn) {
self.onException(e);
}
function handleException(e, queueableFn) {
onException(e, queueableFn);
if (!self.catchException(e)) {
//TODO: set a var when we catch an exception and
//use a finally block to close the loop in a nice way..
@@ -1807,6 +1853,7 @@ getJasmineRequireObj().Suite = function() {
this.resultCallback = attrs.resultCallback || function() {};
this.clearStack = attrs.clearStack || function(fn) {fn();};
this.expectationFactory = attrs.expectationFactory;
this.expectationResultFactory = attrs.expectationResultFactory;
this.beforeFns = [];
this.afterFns = [];
@@ -1821,7 +1868,8 @@ getJasmineRequireObj().Suite = function() {
id: this.id,
status: this.disabled ? 'disabled' : '',
description: this.description,
fullName: this.getFullName()
fullName: this.getFullName(),
failedExpectations: []
};
}
@@ -1873,7 +1921,7 @@ getJasmineRequireObj().Suite = function() {
var allFns = [];
if (this.isExecutable()) {
allFns = this.beforeAllFns;
allFns = allFns.concat(this.beforeAllFns);
for (var i = 0; i < this.children.length; i++) {
allFns.push(wrapChildAsAsync(this.children[i]));
@@ -1928,19 +1976,43 @@ getJasmineRequireObj().Suite = function() {
};
Suite.prototype.onException = function() {
for (var i = 0; i < this.children.length; i++) {
var child = this.children[i];
child.onException.apply(child, arguments);
if(isAfterAll(this.children)) {
var data = {
matcherName: '',
passed: false,
expected: '',
actual: '',
error: arguments[0]
};
this.result.failedExpectations.push(this.expectationResultFactory(data));
} else {
for (var i = 0; i < this.children.length; i++) {
var child = this.children[i];
child.onException.apply(child, arguments);
}
}
};
Suite.prototype.addExpectationResult = function () {
for (var i = 0; i < this.children.length; i++) {
var child = this.children[i];
child.addExpectationResult.apply(child, arguments);
if(isAfterAll(this.children) && isFailure(arguments)){
var data = arguments[1];
this.result.failedExpectations.push(this.expectationResultFactory(data));
} else {
for (var i = 0; i < this.children.length; i++) {
var child = this.children[i];
child.addExpectationResult.apply(child, arguments);
}
}
};
function isAfterAll(children) {
return children && children[0].result.status;
}
function isFailure(args) {
return !args[0];
}
function clone(obj) {
var clonedObj = {};
for (var prop in obj) {