diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js
index 74952879..724b6b97 100644
--- a/lib/jasmine-core/jasmine-html.js
+++ b/lib/jasmine-core/jasmine-html.js
@@ -93,6 +93,10 @@ jasmineRequire.HtmlReporter = function(j$) {
currentParent.addChild(result, 'spec');
};
+ this.afterAllException = function(error) {
+ console.error(error);
+ };
+
var failures = [];
this.specDone = function(result) {
if (result.status != 'disabled') {
diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js
index 27ccdcf9..ca98bd43 100644
--- a/lib/jasmine-core/jasmine.js
+++ b/lib/jasmine-core/jasmine.js
@@ -408,7 +408,8 @@ getJasmineRequireObj().Env = function(j$) {
'suiteStarted',
'suiteDone',
'specStarted',
- 'specDone'
+ 'specDone',
+ 'afterAllException'
]);
this.specFilter = function() {
@@ -539,6 +540,7 @@ 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};
@@ -721,7 +723,7 @@ getJasmineRequireObj().Env = function(j$) {
};
this.afterAll = function(afterAllFunction) {
- currentDeclarationSuite.afterAll({ fn: afterAllFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
+ currentDeclarationSuite.afterAll({ fn: afterAllFunction, isAfterAll: true, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.pending = function() {
@@ -1581,6 +1583,7 @@ 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() {
@@ -1588,7 +1591,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
};
QueueRunner.prototype.run = function(queueableFns, recursiveIndex) {
- var length = queueableFns.length,
+ var runner = this,
+ length = queueableFns.length,
self = this,
iterativeIndex;
@@ -1611,6 +1615,9 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
queueableFn.fn.call(self.userContext);
} catch (e) {
+ if(queueableFn.isAfterAll){
+ runner.reporter.afterAllException(e);
+ }
handleException(e);
}
}
@@ -1635,6 +1642,9 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
queueableFn.fn.call(self.userContext, next);
} catch (e) {
+ if(queueableFn.isAfterAll) {
+ runner.reporter.afterAllException(e);
+ }
handleException(e);
next();
}
diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js
index 6f8e0dbb..7010c043 100644
--- a/spec/core/integration/EnvSpec.js
+++ b/spec/core/integration/EnvSpec.js
@@ -307,7 +307,7 @@ describe("Env integration", function() {
expect(reporter.specDone.calls.argsFor(1)[0].failedExpectations[0].message)
.toEqual("Expected 1 to be 2.");
done();
- });
+ });
env.addReporter(reporter);
@@ -328,6 +328,58 @@ describe("Env integration", function() {
env.execute();
});
+ it("reports when afterAll throws an exception", function(done) {
+ var env = new j$.Env(),
+ error = new Error('After All Exception'),
+ reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','afterAllException']);
+
+
+ reporter.jasmineDone.and.callFake(function() {
+ expect(reporter.afterAllException).toHaveBeenCalledWith(error);
+ done();
+ });
+
+ env.addReporter(reporter);
+
+ env.describe('my suite', function() {
+ env.it('my spec', function() {
+ });
+
+ env.afterAll(function() {
+ throw error;
+ });
+ });
+
+ env.execute();
+ });
+
+ it("reports when an async afterAll throws an exception", function(done) {
+ var env = new j$.Env(),
+ error = new Error('After All Exception'),
+ reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','afterAllException']);
+
+
+ reporter.jasmineDone.and.callFake(function() {
+ expect(reporter.afterAllException).toHaveBeenCalledWith(error);
+ done();
+ });
+
+ env.addReporter(reporter);
+
+ env.describe('my suite', function() {
+ env.it('my spec', function() {
+ });
+
+ env.afterAll(function(done) {
+ throw error;
+ });
+ });
+
+ env.execute();
+ });
+
+
+
it("Allows specifying which specs and suites to run", function(done) {
var env = new j$.Env(),
calls = [],
diff --git a/spec/html/HtmlReporterSpec.js b/spec/html/HtmlReporterSpec.js
index 0919f3ed..25b4ae71 100644
--- a/spec/html/HtmlReporterSpec.js
+++ b/spec/html/HtmlReporterSpec.js
@@ -130,6 +130,27 @@ describe("New HtmlReporter", function() {
});
});
+ describe("when afterAllException is called", function () {
+ it("sends a console error", function(){
+ var env = new j$.Env(),
+ error = new Error('After all exception!'),
+ container = document.createElement('div'),
+ getContainer = function () { return container; },
+ reporter = new j$.HtmlReporter({
+ env: env,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); },
+ getContainer: getContainer
+ });
+
+ reporter.initialize();
+
+ spyOn(window.console, 'error');
+ reporter.afterAllException(error);
+ expect(window.console.error).toHaveBeenCalled();
+ });
+ });
+
describe("when Jasmine is done", function() {
it("reports the run time", function() {
var env = new j$.Env(),
diff --git a/src/core/Env.js b/src/core/Env.js
index fc2b6e80..59ed8767 100644
--- a/src/core/Env.js
+++ b/src/core/Env.js
@@ -34,7 +34,8 @@ getJasmineRequireObj().Env = function(j$) {
'suiteStarted',
'suiteDone',
'specStarted',
- 'specDone'
+ 'specDone',
+ 'afterAllException'
]);
this.specFilter = function() {
@@ -165,6 +166,7 @@ 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};
@@ -347,7 +349,7 @@ getJasmineRequireObj().Env = function(j$) {
};
this.afterAll = function(afterAllFunction) {
- currentDeclarationSuite.afterAll({ fn: afterAllFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
+ currentDeclarationSuite.afterAll({ fn: afterAllFunction, isAfterAll: true, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.pending = function() {
diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js
index 1ec3c16e..726591f4 100644
--- a/src/core/QueueRunner.js
+++ b/src/core/QueueRunner.js
@@ -18,6 +18,7 @@ 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() {
@@ -25,7 +26,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
};
QueueRunner.prototype.run = function(queueableFns, recursiveIndex) {
- var length = queueableFns.length,
+ var runner = this,
+ length = queueableFns.length,
self = this,
iterativeIndex;
@@ -48,6 +50,9 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
queueableFn.fn.call(self.userContext);
} catch (e) {
+ if(queueableFn.isAfterAll){
+ runner.reporter.afterAllException(e);
+ }
handleException(e);
}
}
@@ -72,6 +77,9 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
queueableFn.fn.call(self.userContext, next);
} catch (e) {
+ if(queueableFn.isAfterAll) {
+ runner.reporter.afterAllException(e);
+ }
handleException(e);
next();
}
diff --git a/src/html/HtmlReporter.js b/src/html/HtmlReporter.js
index a81f6583..e03b8948 100644
--- a/src/html/HtmlReporter.js
+++ b/src/html/HtmlReporter.js
@@ -64,6 +64,10 @@ jasmineRequire.HtmlReporter = function(j$) {
currentParent.addChild(result, 'spec');
};
+ this.afterAllException = function(error) {
+ console.error(error);
+ };
+
var failures = [];
this.specDone = function(result) {
if (result.status != 'disabled') {