jasmine.Queue iterates by looping rather than recursing, so stack overflows should be less likely.
This commit is contained in:
parent
b7549196da
commit
5659a1e79e
|
@ -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',
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
73
src/Queue.js
73
src/Queue.js
|
@ -29,43 +29,54 @@ 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;
|
||||||
if (self.index < self.blocks.length) {
|
var goAgain = true;
|
||||||
var calledSynchronously = true;
|
|
||||||
var completedSynchronously = false;
|
|
||||||
|
|
||||||
var onComplete = function () {
|
while (goAgain) {
|
||||||
if (jasmine.Queue.UNROLL && calledSynchronously) {
|
goAgain = false;
|
||||||
completedSynchronously = true;
|
|
||||||
return;
|
if (self.index < self.blocks.length) {
|
||||||
|
var calledSynchronously = true;
|
||||||
|
var completedSynchronously = false;
|
||||||
|
|
||||||
|
var onComplete = function () {
|
||||||
|
if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
|
||||||
|
completedSynchronously = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.offset = 0;
|
||||||
|
self.index++;
|
||||||
|
|
||||||
|
var now = new Date().getTime();
|
||||||
|
if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
|
||||||
|
self.env.lastUpdate = now;
|
||||||
|
self.env.setTimeout(function() {
|
||||||
|
self.next_();
|
||||||
|
}, 0);
|
||||||
|
} else {
|
||||||
|
if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
|
||||||
|
goAgain = true;
|
||||||
|
} else {
|
||||||
|
self.next_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.blocks[self.index].execute(onComplete);
|
||||||
|
|
||||||
|
calledSynchronously = false;
|
||||||
|
if (completedSynchronously) {
|
||||||
|
onComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.offset = 0;
|
} else {
|
||||||
self.index++;
|
self.running = false;
|
||||||
|
if (self.onComplete) {
|
||||||
var now = new Date().getTime();
|
self.onComplete();
|
||||||
if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
|
|
||||||
self.env.lastUpdate = now;
|
|
||||||
self.env.setTimeout(function() {
|
|
||||||
self.next_();
|
|
||||||
}, 0);
|
|
||||||
} else {
|
|
||||||
self.next_();
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
self.blocks[self.index].execute(onComplete);
|
|
||||||
|
|
||||||
calledSynchronously = false;
|
|
||||||
if (completedSynchronously) {
|
|
||||||
onComplete();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.running = false;
|
|
||||||
if (self.onComplete) {
|
|
||||||
self.onComplete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue