Slight refactoring of clearing timeouts when an exception is thrown
This commit is contained in:
@@ -266,7 +266,8 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
};
|
||||
|
||||
Spec.prototype.execute = function(onComplete) {
|
||||
var self = this;
|
||||
var self = this,
|
||||
timeout;
|
||||
|
||||
this.onStart(this);
|
||||
|
||||
@@ -277,26 +278,25 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
|
||||
function timeoutable(fn) {
|
||||
return function(done) {
|
||||
var timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
|
||||
timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
|
||||
onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
|
||||
done();
|
||||
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
|
||||
|
||||
var callDone = function() {
|
||||
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
|
||||
clearTimeoutable();
|
||||
done();
|
||||
};
|
||||
|
||||
try {
|
||||
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
|
||||
}
|
||||
catch (e) {
|
||||
onException(e);
|
||||
callDone();
|
||||
}
|
||||
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
|
||||
};
|
||||
}
|
||||
|
||||
function clearTimeoutable() {
|
||||
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
|
||||
timeout = void 0;
|
||||
}
|
||||
|
||||
var befores = this.beforeFns() || [],
|
||||
afters = this.afterFns() || [],
|
||||
thisOne = (this.fn.length) ? timeoutable(this.fn) : this.fn;
|
||||
@@ -309,6 +309,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
});
|
||||
|
||||
function onException(e) {
|
||||
clearTimeoutable();
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
self.pend();
|
||||
return;
|
||||
|
||||
@@ -218,42 +218,24 @@ describe("Spec", function() {
|
||||
expect(specNameSpy.calls.mostRecent().args[0].id).toEqual(spec.id);
|
||||
});
|
||||
|
||||
it("resets the timeout timer when an async spec throws an exception", function(done) {
|
||||
var handleException = jasmine.createSpy('exception handler'),
|
||||
it("resets the timeout timer when an async spec throws an exception", function() {
|
||||
var queueRunnerSpy = jasmine.createSpy('queueRunner'),
|
||||
clearTimeoutSpy = jasmine.createSpy('clear timeout'),
|
||||
spec = new j$.Spec({
|
||||
fn: function(done) { throw new Error('test'); },
|
||||
fn: function(done) { },
|
||||
catchExceptions: function() { return true; },
|
||||
expectationResultFactory: handleException,
|
||||
timer: {
|
||||
// Force timeout to 0 to postpone execution to next tick
|
||||
// without using the default 5s interval
|
||||
setTimeout: function (fn) { return setTimeout(fn, 0); },
|
||||
clearTimeout: clearTimeout
|
||||
setTimeout: function () { return 920; },
|
||||
clearTimeout: clearTimeoutSpy
|
||||
},
|
||||
queueRunnerFactory: function (attrs) {
|
||||
// Fake the "run" method of a regular queue runner
|
||||
// for an async spec.
|
||||
try {
|
||||
attrs.fns[0].call({}, function () {});
|
||||
} catch (e) {
|
||||
handleException(e);
|
||||
}
|
||||
}
|
||||
queueRunnerFactory: queueRunnerSpy
|
||||
});
|
||||
|
||||
// Spec execution will create the timeout timer that would report
|
||||
// a failure on next tick unless it gets properly cleared before
|
||||
// the end of this tick.
|
||||
spec.execute();
|
||||
queueRunnerSpy.calls.mostRecent().args[0].fns[0]();
|
||||
queueRunnerSpy.calls.mostRecent().args[0].onException(new Error());
|
||||
|
||||
// Run the expect clause on next tick to detect the case when the
|
||||
// timeout timer was not properly reset. The exception handler is
|
||||
// called once when the error is thrown. It is called twice when
|
||||
// the timeout timer is not properly reset.
|
||||
setTimeout(function () {
|
||||
expect(handleException.calls.count()).toEqual(1);
|
||||
done();
|
||||
}, 0);
|
||||
expect(clearTimeoutSpy).toHaveBeenCalledWith(920);
|
||||
});
|
||||
|
||||
describe("when a spec is marked pending during execution", function() {
|
||||
|
||||
@@ -41,7 +41,8 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
};
|
||||
|
||||
Spec.prototype.execute = function(onComplete) {
|
||||
var self = this;
|
||||
var self = this,
|
||||
timeout;
|
||||
|
||||
this.onStart(this);
|
||||
|
||||
@@ -52,26 +53,25 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
|
||||
function timeoutable(fn) {
|
||||
return function(done) {
|
||||
var timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
|
||||
timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
|
||||
onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
|
||||
done();
|
||||
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
|
||||
|
||||
var callDone = function() {
|
||||
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
|
||||
clearTimeoutable();
|
||||
done();
|
||||
};
|
||||
|
||||
try {
|
||||
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
|
||||
}
|
||||
catch (e) {
|
||||
onException(e);
|
||||
callDone();
|
||||
}
|
||||
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
|
||||
};
|
||||
}
|
||||
|
||||
function clearTimeoutable() {
|
||||
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
|
||||
timeout = void 0;
|
||||
}
|
||||
|
||||
var befores = this.beforeFns() || [],
|
||||
afters = this.afterFns() || [],
|
||||
thisOne = (this.fn.length) ? timeoutable(this.fn) : this.fn;
|
||||
@@ -84,6 +84,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
});
|
||||
|
||||
function onException(e) {
|
||||
clearTimeoutable();
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
self.pend();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user