jasmine.Queue iterates by looping rather than recursing, so stack overflows should be less likely.

This commit is contained in:
Christian Williams 2009-10-12 23:09:51 -05:00
parent b7549196da
commit 5659a1e79e
3 changed files with 66 additions and 31 deletions

View File

@ -39,6 +39,7 @@
'suites/ExceptionsSpec.js', 'suites/ExceptionsSpec.js',
'suites/TrivialReporterSpec.js', 'suites/TrivialReporterSpec.js',
'suites/MatchersSpec.js', 'suites/MatchersSpec.js',
'suites/QueueSpec.js',
'suites/ReporterSpec.js', 'suites/ReporterSpec.js',
'suites/MultiReporterSpec.js', 'suites/MultiReporterSpec.js',
'suites/PrettyPrintSpec.js', 'suites/PrettyPrintSpec.js',

23
spec/suites/QueueSpec.js Normal file
View File

@ -0,0 +1,23 @@
describe("jasmine.Queue", function() {
it("should not call itself recursively, so we don't get stack overflow errors", function() {
var queue = new jasmine.Queue(new jasmine.Env());
queue.add(new jasmine.Block(null, function() {}));
queue.add(new jasmine.Block(null, function() {}));
queue.add(new jasmine.Block(null, function() {}));
queue.add(new jasmine.Block(null, function() {}));
var nestCount = 0;
var maxNestCount = 0;
var nextCallCount = 0;
queue.next_ = function() {
nestCount++;
if (nestCount > maxNestCount) maxNestCount = nestCount;
jasmine.Queue.prototype.next_.apply(queue, arguments);
nestCount--;
};
queue.start();
expect(maxNestCount).toEqual(1);
});
});

View File

@ -29,16 +29,21 @@ jasmine.Queue.prototype.isRunning = function() {
return this.running; return this.running;
}; };
jasmine.Queue.UNROLL = true; jasmine.Queue.LOOP_DONT_RECURSE = true;
jasmine.Queue.prototype.next_ = function() { jasmine.Queue.prototype.next_ = function() {
var self = this; var self = this;
var goAgain = true;
while (goAgain) {
goAgain = false;
if (self.index < self.blocks.length) { if (self.index < self.blocks.length) {
var calledSynchronously = true; var calledSynchronously = true;
var completedSynchronously = false; var completedSynchronously = false;
var onComplete = function () { var onComplete = function () {
if (jasmine.Queue.UNROLL && calledSynchronously) { if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
completedSynchronously = true; completedSynchronously = true;
return; return;
} }
@ -52,9 +57,13 @@ jasmine.Queue.prototype.next_ = function() {
self.env.setTimeout(function() { self.env.setTimeout(function() {
self.next_(); self.next_();
}, 0); }, 0);
} else {
if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
goAgain = true;
} else { } else {
self.next_(); self.next_();
} }
}
}; };
self.blocks[self.index].execute(onComplete); self.blocks[self.index].execute(onComplete);
@ -62,12 +71,14 @@ jasmine.Queue.prototype.next_ = function() {
if (completedSynchronously) { if (completedSynchronously) {
onComplete(); onComplete();
} }
} else { } else {
self.running = false; self.running = false;
if (self.onComplete) { if (self.onComplete) {
self.onComplete(); self.onComplete();
} }
} }
}
}; };
jasmine.Queue.prototype.results = function() { jasmine.Queue.prototype.results = function() {