Extract afterAll checking from queueRunner

This commit is contained in:
slackersoft
2014-06-20 08:16:42 -07:00
parent f0892a55aa
commit 1bad048c15
3 changed files with 44 additions and 27 deletions

View File

@@ -95,13 +95,15 @@ describe("QueueRunner", function() {
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() { it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
var timeout = 3, var timeout = 3,
beforeFn = { fn: function(done) { }, timeout: function() { return timeout; } }, beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
queueableFn = { fn: jasmine.createSpy('fn') }, queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
onComplete = jasmine.createSpy('onComplete'), onComplete = jasmine.createSpy('onComplete'),
reportException = jasmine.createSpy('reportException'),
onException = jasmine.createSpy('onException'), onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({ queueRunner = new j$.QueueRunner({
queueableFns: [beforeFn, queueableFn], queueableFns: [beforeFn, queueableFn],
onComplete: onComplete, onComplete: onComplete,
reportException: reportException,
onException: onException onException: onException
}); });
@@ -110,6 +112,7 @@ describe("QueueRunner", function() {
jasmine.clock().tick(timeout); jasmine.clock().tick(timeout);
expect(reportException).toHaveBeenCalledWith(jasmine.any(Error), 'before');
expect(onException).toHaveBeenCalledWith(jasmine.any(Error)); expect(onException).toHaveBeenCalledWith(jasmine.any(Error));
expect(queueableFn.fn).toHaveBeenCalled(); expect(queueableFn.fn).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled(); expect(onComplete).toHaveBeenCalled();
@@ -119,10 +122,12 @@ describe("QueueRunner", function() {
var beforeFn = { fn: function(done) { } }, var beforeFn = { fn: function(done) { } },
queueableFn = { fn: jasmine.createSpy('fn') }, queueableFn = { fn: jasmine.createSpy('fn') },
onComplete = jasmine.createSpy('onComplete'), onComplete = jasmine.createSpy('onComplete'),
reportException = jasmine.createSpy('reportException'),
onException = jasmine.createSpy('onException'), onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({ queueRunner = new j$.QueueRunner({
queueableFns: [beforeFn, queueableFn], queueableFns: [beforeFn, queueableFn],
onComplete: onComplete, onComplete: onComplete,
reportException: reportException,
onException: onException, onException: onException,
}); });
@@ -131,37 +136,44 @@ describe("QueueRunner", function() {
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL); jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(reportException).not.toHaveBeenCalled();
expect(onException).not.toHaveBeenCalled(); expect(onException).not.toHaveBeenCalled();
expect(queueableFn.fn).not.toHaveBeenCalled(); expect(queueableFn.fn).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled(); expect(onComplete).not.toHaveBeenCalled();
}); });
it("clears the timeout when an async function throws an exception, to prevent additional onException calls", function() { it("clears the timeout when an async function throws an exception, to prevent additional exception reporting", function() {
var queueableFn = { fn: function(done) { throw new Error("error!"); } }, var queueableFn = { fn: function(done) { throw new Error("error!"); } },
onComplete = jasmine.createSpy('onComplete'), onComplete = jasmine.createSpy('onComplete'),
reportException = jasmine.createSpy('reportException'),
onException = jasmine.createSpy('onException'), onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({ queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn], queueableFns: [queueableFn],
onComplete: onComplete, onComplete: onComplete,
reportException: reportException,
onException: onException onException: onException
}); });
queueRunner.execute(); queueRunner.execute();
expect(onComplete).toHaveBeenCalled(); expect(onComplete).toHaveBeenCalled();
expect(reportException).toHaveBeenCalled();
expect(onException).toHaveBeenCalled(); expect(onException).toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL); jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(reportException.calls.count()).toEqual(1);
expect(onException.calls.count()).toEqual(1); expect(onException.calls.count()).toEqual(1);
}); });
it("clears the timeout when the done callback is called", function() { it("clears the timeout when the done callback is called", function() {
var queueableFn = { fn: function(done) { done(); } }, var queueableFn = { fn: function(done) { done(); } },
onComplete = jasmine.createSpy('onComplete'), onComplete = jasmine.createSpy('onComplete'),
reportException = jasmine.createSpy('reportException'),
onException = jasmine.createSpy('onException'), onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({ queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn], queueableFns: [queueableFn],
onComplete: onComplete, onComplete: onComplete,
reportException: reportException
onException: onException onException: onException
}); });
@@ -170,6 +182,7 @@ describe("QueueRunner", function() {
expect(onComplete).toHaveBeenCalled(); expect(onComplete).toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL); jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(reportException).not.toHaveBeenCalled();
expect(onException).not.toHaveBeenCalled(); expect(onException).not.toHaveBeenCalled();
}); });
@@ -200,19 +213,23 @@ describe("QueueRunner", function() {
}); });
}); });
it("calls an exception handler when an exception is thrown in a fn", function() { it("calls exception handlers when an exception is thrown in a fn", function() {
var queueableFn = { fn: function() { var queueableFn = { type: 'queueable',
fn: function() {
throw new Error('fake error'); throw new Error('fake error');
} }, } },
exceptionCallback = jasmine.createSpy('exception callback'), exceptionCallback = jasmine.createSpy('exception callback'),
onExceptionCallback = jasmine.createSpy('on exception callback'),
queueRunner = new j$.QueueRunner({ queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn], queueableFns: [queueableFn],
onException: exceptionCallback reportException: exceptionCallback,
onException: onExceptionCallback
}); });
queueRunner.execute(); queueRunner.execute();
expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error)); expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error), 'queueable');
expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
}); });
it("rethrows an exception if told to", function() { it("rethrows an exception if told to", function() {

View File

@@ -166,9 +166,13 @@ getJasmineRequireObj().Env = function(j$) {
var queueRunnerFactory = function(options) { var queueRunnerFactory = function(options) {
options.catchException = catchException; options.catchException = catchException;
options.reporter = reporter;
options.clearStack = options.clearStack || clearStack; options.clearStack = options.clearStack || clearStack;
options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}; options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
options.reportException = function(e, type) {
if (type === 'afterAll') {
reporter.afterAllError(e);
}
};
new j$.QueueRunner(options).execute(); new j$.QueueRunner(options).execute();
}; };
@@ -296,7 +300,7 @@ getJasmineRequireObj().Env = function(j$) {
expectationResultFactory: expectationResultFactory, expectationResultFactory: expectationResultFactory,
queueRunnerFactory: queueRunnerFactory, queueRunnerFactory: queueRunnerFactory,
userContext: function() { return suite.clonedSharedUserContext(); }, 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; runnableLookupTable[spec.id] = spec;
@@ -337,19 +341,19 @@ getJasmineRequireObj().Env = function(j$) {
}; };
this.beforeEach = function(beforeEachFunction) { 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) { 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) { 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) { 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() { this.pending = function() {

View File

@@ -18,7 +18,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
this.catchException = attrs.catchException || function() { return true; }; this.catchException = attrs.catchException || function() { return true; };
this.userContext = attrs.userContext || {}; this.userContext = attrs.userContext || {};
this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout}; this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
this.reporter = attrs.reporter; this.reportException = attrs.reportException || function() {};
} }
QueueRunner.prototype.execute = function() { QueueRunner.prototype.execute = function() {
@@ -50,10 +50,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try { try {
queueableFn.fn.call(self.userContext); queueableFn.fn.call(self.userContext);
} catch (e) { } catch (e) {
if(queueableFn.isAfterAll){ handleException(e, queueableFn);
runner.reporter.afterAllError(e);
}
handleException(e);
} }
} }
@@ -70,10 +67,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
if (queueableFn.timeout) { if (queueableFn.timeout) {
timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() { timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
var error = 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.');
if (queueableFn.isAfterAll) { onException(error, queueableFn);
runner.reporter.afterAllError(error);
}
self.onException(error);
next(); next();
}, queueableFn.timeout()]]); }, queueableFn.timeout()]]);
} }
@@ -81,16 +75,18 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try { try {
queueableFn.fn.call(self.userContext, next); queueableFn.fn.call(self.userContext, next);
} catch (e) { } catch (e) {
if(queueableFn.isAfterAll) { handleException(e, queueableFn);
runner.reporter.afterAllError(e);
}
handleException(e);
next(); next();
} }
} }
function handleException(e) { function onException(e, queueableFn) {
self.reportException(e, queueableFn.type);
self.onException(e); self.onException(e);
}
function handleException(e, queueableFn) {
onException(e, queueableFn);
if (!self.catchException(e)) { if (!self.catchException(e)) {
//TODO: set a var when we catch an exception and //TODO: set a var when we catch an exception and
//use a finally block to close the loop in a nice way.. //use a finally block to close the loop in a nice way..