Suites report errors in afterAlls in the suiteDone event
- remove `afterAllEvent` from reporters
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user