Refactor QueueRunner and remove references to functions that Jasmine is done with

[finishes #56030214]
This commit is contained in:
Gregg Van Hove
2018-01-11 17:19:26 -08:00
parent cf2f922e30
commit e2a191b116
6 changed files with 227 additions and 190 deletions

View File

@@ -603,6 +603,7 @@ getJasmineRequireObj().Spec = function(j$) {
this.queueRunnerFactory(runnerConfig);
function complete(enabledAgain) {
self.queueableFn.fn = null;
self.result.status = self.status(enabledAgain);
self.resultCallback(self.result);
@@ -4513,6 +4514,103 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}
};
QueueRunner.prototype.clearTimeout = function(timeoutId) {
Function.prototype.apply.apply(this.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
};
QueueRunner.prototype.setTimeout = function(fn, timeout) {
return Function.prototype.apply.apply(this.timeout.setTimeout, [j$.getGlobal(), [fn, timeout]]);
};
QueueRunner.prototype.attempt = function attempt(iterativeIndex) {
var self = this, completedSynchronously = true,
handleError = function(error) {
onException(error);
next();
},
cleanup = once(function() {
self.clearTimeout(timeoutId);
self.globalErrors.popListener(handleError);
}),
next = once(function () {
cleanup();
function runNext() {
if (self.completeOnFirstError && errored) {
self.skipToCleanup(iterativeIndex);
} else {
self.run(iterativeIndex + 1);
}
}
if (completedSynchronously) {
self.setTimeout(runNext);
} else {
runNext();
}
}),
errored = false,
queueableFn = self.queueableFns[iterativeIndex],
timeoutId;
next.fail = function() {
self.fail.apply(null, arguments);
errored = true;
next();
};
self.globalErrors.pushListener(handleError);
if (queueableFn.timeout) {
timeoutId = self.setTimeout(function() {
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
onException(error);
next();
}, queueableFn.timeout());
}
try {
if (queueableFn.fn.length === 0) {
var maybeThenable = queueableFn.fn.call(self.userContext);
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
maybeThenable.then(next, onPromiseRejection);
completedSynchronously = false;
return { completedSynchronously: false };
}
} else {
queueableFn.fn.call(self.userContext, next);
completedSynchronously = false;
return { completedSynchronously: false };
}
} catch (e) {
handleException(e, queueableFn);
errored = true;
}
cleanup();
return { completedSynchronously: true, errored: errored };
function onException(e) {
self.onException(e);
errored = true;
}
function onPromiseRejection(e) {
onException(e);
next();
}
function handleException(e, queueableFn) {
onException(e);
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..
throw e;
}
}
};
QueueRunner.prototype.run = function(recursiveIndex) {
var length = this.queueableFns.length,
self = this,
@@ -4520,7 +4618,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
var result = attempt(iterativeIndex);
var result = this.attempt(iterativeIndex);
if (!result.completedSynchronously) {
return;
@@ -4537,100 +4635,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
self.onComplete();
});
function attempt() {
var clearTimeout = function () {
Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
},
setTimeout = function(delayedFn, delay) {
return Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [delayedFn, delay]]);
},
completedSynchronously = true,
handleError = function(error) {
onException(error);
next();
},
cleanup = once(function() {
clearTimeout(timeoutId);
self.globalErrors.popListener(handleError);
}),
next = once(function () {
cleanup();
function runNext() {
if (self.completeOnFirstError && errored) {
self.skipToCleanup(iterativeIndex);
} else {
self.run(iterativeIndex + 1);
}
}
if (completedSynchronously) {
setTimeout(runNext);
} else {
runNext();
}
}),
errored = false,
queueableFn = self.queueableFns[iterativeIndex],
timeoutId;
next.fail = function() {
self.fail.apply(null, arguments);
errored = true;
next();
};
self.globalErrors.pushListener(handleError);
if (queueableFn.timeout) {
timeoutId = setTimeout(function() {
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
onException(error);
next();
}, queueableFn.timeout());
}
try {
if (queueableFn.fn.length === 0) {
var maybeThenable = queueableFn.fn.call(self.userContext);
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
maybeThenable.then(next, onPromiseRejection);
completedSynchronously = false;
return { completedSynchronously: false };
}
} else {
queueableFn.fn.call(self.userContext, next);
completedSynchronously = false;
return { completedSynchronously: false };
}
} catch (e) {
handleException(e, queueableFn);
errored = true;
}
cleanup();
return { completedSynchronously: true, errored: errored };
function onException(e) {
self.onException(e);
errored = true;
}
function onPromiseRejection(e) {
onException(e);
next();
}
function handleException(e, queueableFn) {
onException(e);
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..
throw e;
}
}
}
};
return QueueRunner;
@@ -5500,6 +5504,19 @@ getJasmineRequireObj().Suite = function(j$) {
this.afterAllFns.unshift(fn);
};
function removeFns(queueableFns) {
for(var i = 0; i < queueableFns.length; i++) {
queueableFns[i].fn = null;
}
}
Suite.prototype.cleanupBeforeAfter = function() {
removeFns(this.beforeAllFns);
removeFns(this.afterAllFns);
removeFns(this.beforeFns);
removeFns(this.afterFns);
};
Suite.prototype.addChild = function(child) {
this.children.push(child);
};
@@ -5796,6 +5813,7 @@ getJasmineRequireObj().TreeProcessor = function() {
queueRunnerFactory({
onComplete: function() {
node.cleanupBeforeAfter();
nodeComplete(node, node.getResult());
done();
},

View File

@@ -17,6 +17,7 @@ describe("TreeProcessor", function() {
this.getResult = jasmine.createSpy(this.id + '#execute');
this.beforeAllFns = attrs.beforeAllFns || [];
this.afterAllFns = attrs.afterAllFns || [];
this.cleanupBeforeAfter = function() { };
}
function Leaf(attrs) {

View File

@@ -43,6 +43,103 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}
};
QueueRunner.prototype.clearTimeout = function(timeoutId) {
Function.prototype.apply.apply(this.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
};
QueueRunner.prototype.setTimeout = function(fn, timeout) {
return Function.prototype.apply.apply(this.timeout.setTimeout, [j$.getGlobal(), [fn, timeout]]);
};
QueueRunner.prototype.attempt = function attempt(iterativeIndex) {
var self = this, completedSynchronously = true,
handleError = function(error) {
onException(error);
next();
},
cleanup = once(function() {
self.clearTimeout(timeoutId);
self.globalErrors.popListener(handleError);
}),
next = once(function () {
cleanup();
function runNext() {
if (self.completeOnFirstError && errored) {
self.skipToCleanup(iterativeIndex);
} else {
self.run(iterativeIndex + 1);
}
}
if (completedSynchronously) {
self.setTimeout(runNext);
} else {
runNext();
}
}),
errored = false,
queueableFn = self.queueableFns[iterativeIndex],
timeoutId;
next.fail = function() {
self.fail.apply(null, arguments);
errored = true;
next();
};
self.globalErrors.pushListener(handleError);
if (queueableFn.timeout) {
timeoutId = self.setTimeout(function() {
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
onException(error);
next();
}, queueableFn.timeout());
}
try {
if (queueableFn.fn.length === 0) {
var maybeThenable = queueableFn.fn.call(self.userContext);
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
maybeThenable.then(next, onPromiseRejection);
completedSynchronously = false;
return { completedSynchronously: false };
}
} else {
queueableFn.fn.call(self.userContext, next);
completedSynchronously = false;
return { completedSynchronously: false };
}
} catch (e) {
handleException(e, queueableFn);
errored = true;
}
cleanup();
return { completedSynchronously: true, errored: errored };
function onException(e) {
self.onException(e);
errored = true;
}
function onPromiseRejection(e) {
onException(e);
next();
}
function handleException(e, queueableFn) {
onException(e);
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..
throw e;
}
}
};
QueueRunner.prototype.run = function(recursiveIndex) {
var length = this.queueableFns.length,
self = this,
@@ -50,7 +147,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
var result = attempt(iterativeIndex);
var result = this.attempt(iterativeIndex);
if (!result.completedSynchronously) {
return;
@@ -67,100 +164,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
self.onComplete();
});
function attempt() {
var clearTimeout = function () {
Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
},
setTimeout = function(delayedFn, delay) {
return Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [delayedFn, delay]]);
},
completedSynchronously = true,
handleError = function(error) {
onException(error);
next();
},
cleanup = once(function() {
clearTimeout(timeoutId);
self.globalErrors.popListener(handleError);
}),
next = once(function () {
cleanup();
function runNext() {
if (self.completeOnFirstError && errored) {
self.skipToCleanup(iterativeIndex);
} else {
self.run(iterativeIndex + 1);
}
}
if (completedSynchronously) {
setTimeout(runNext);
} else {
runNext();
}
}),
errored = false,
queueableFn = self.queueableFns[iterativeIndex],
timeoutId;
next.fail = function() {
self.fail.apply(null, arguments);
errored = true;
next();
};
self.globalErrors.pushListener(handleError);
if (queueableFn.timeout) {
timeoutId = setTimeout(function() {
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
onException(error);
next();
}, queueableFn.timeout());
}
try {
if (queueableFn.fn.length === 0) {
var maybeThenable = queueableFn.fn.call(self.userContext);
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
maybeThenable.then(next, onPromiseRejection);
completedSynchronously = false;
return { completedSynchronously: false };
}
} else {
queueableFn.fn.call(self.userContext, next);
completedSynchronously = false;
return { completedSynchronously: false };
}
} catch (e) {
handleException(e, queueableFn);
errored = true;
}
cleanup();
return { completedSynchronously: true, errored: errored };
function onException(e) {
self.onException(e);
errored = true;
}
function onPromiseRejection(e) {
onException(e);
next();
}
function handleException(e, queueableFn) {
onException(e);
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..
throw e;
}
}
}
};
return QueueRunner;

View File

@@ -81,6 +81,7 @@ getJasmineRequireObj().Spec = function(j$) {
this.queueRunnerFactory(runnerConfig);
function complete(enabledAgain) {
self.queueableFn.fn = null;
self.result.status = self.status(enabledAgain);
self.resultCallback(self.result);

View File

@@ -65,6 +65,19 @@ getJasmineRequireObj().Suite = function(j$) {
this.afterAllFns.unshift(fn);
};
function removeFns(queueableFns) {
for(var i = 0; i < queueableFns.length; i++) {
queueableFns[i].fn = null;
}
}
Suite.prototype.cleanupBeforeAfter = function() {
removeFns(this.beforeAllFns);
removeFns(this.afterAllFns);
removeFns(this.beforeFns);
removeFns(this.afterFns);
};
Suite.prototype.addChild = function(child) {
this.children.push(child);
};

View File

@@ -168,6 +168,7 @@ getJasmineRequireObj().TreeProcessor = function() {
queueRunnerFactory({
onComplete: function() {
node.cleanupBeforeAfter();
nodeComplete(node, node.getResult());
done();
},