From 09fe7b05400c75a93b1299ca350916fe92508954 Mon Sep 17 00:00:00 2001 From: "Davis W. Frank and Sheel Choksi" Date: Tue, 2 Jul 2013 16:05:26 -0700 Subject: [PATCH] Have QueueRunner run specs iteratively if possible, fallback to recursion for async specs This prevents the stack from growing as large for the normal cases and is giving a significant speedup for the performance suite --- lib/jasmine-core/jasmine.js | 33 +++++++++++++++++++-------------- spec/core/QueueRunnerSpec.js | 9 ++++++--- src/core/QueueRunner.js | 29 ++++++++++++++++++----------- src/core/Suite.js | 4 +--- 4 files changed, 44 insertions(+), 31 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 4ca68d1d..9f40ee4a 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1299,19 +1299,26 @@ getJasmineRequireObj().QueueRunner = function() { this.run(this.fns, 0); }; - QueueRunner.prototype.run = function(fns, index) { - if (index >= fns.length) { - this.clearStack(this.onComplete); - return; + QueueRunner.prototype.run = function(fns, recursiveIndex) { + var length = fns.length, + self = this, + iterativeIndex; + + for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) { + var fn = fns[iterativeIndex]; + if (fn.length > 0) { + attempt(function() { fn.call(self, function() { + self.clearStack(function() { self.run(fns, iterativeIndex + 1); }); + }); + }); + return; + } else { + attempt(function() { fn.call(self); }); + } } - var fn = fns[index]; - var self = this; - if (fn.length > 0) { - attempt(function() { fn.call(self, function() { self.run(fns, index + 1); }); }); - } else { - attempt(function() { fn.call(self); }); - self.run(fns, index + 1); + if (iterativeIndex >= length) { + this.onComplete(); } function attempt(fn) { @@ -1549,9 +1556,7 @@ getJasmineRequireObj().Suite = function() { } function wrapChild(child) { - return function(done) { - child.execute(done); - }; + return function() { child.execute(); }; } }; diff --git a/spec/core/QueueRunnerSpec.js b/spec/core/QueueRunnerSpec.js index 9dd90fba..955dedc8 100644 --- a/spec/core/QueueRunnerSpec.js +++ b/spec/core/QueueRunnerSpec.js @@ -115,8 +115,8 @@ describe("QueueRunner", function() { expect(completeCallback).toHaveBeenCalled(); }); - it("calls a provided garbage collection function with the complete callback when done", function() { - var fn = jasmine.createSpy('fn'), + it("calls a provided stack clearing function when done with async specs", function() { + var fn = function(done) { done() }, completeCallback = jasmine.createSpy('completeCallback'), clearStack = jasmine.createSpy('clearStack'), queueRunner = new j$.QueueRunner({ @@ -125,8 +125,11 @@ describe("QueueRunner", function() { onComplete: completeCallback }); + clearStack.andCallFake(function(fn) { fn(); }); + queueRunner.execute(); - expect(clearStack).toHaveBeenCalledWith(completeCallback); + expect(clearStack).toHaveBeenCalled(); + expect(completeCallback).toHaveBeenCalled(); }); }); diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js index 1bd2d403..2d3b0dfe 100644 --- a/src/core/QueueRunner.js +++ b/src/core/QueueRunner.js @@ -12,19 +12,26 @@ getJasmineRequireObj().QueueRunner = function() { this.run(this.fns, 0); }; - QueueRunner.prototype.run = function(fns, index) { - if (index >= fns.length) { - this.clearStack(this.onComplete); - return; + QueueRunner.prototype.run = function(fns, recursiveIndex) { + var length = fns.length, + self = this, + iterativeIndex; + + for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) { + var fn = fns[iterativeIndex]; + if (fn.length > 0) { + attempt(function() { fn.call(self, function() { + self.clearStack(function() { self.run(fns, iterativeIndex + 1); }); + }); + }); + return; + } else { + attempt(function() { fn.call(self); }); + } } - var fn = fns[index]; - var self = this; - if (fn.length > 0) { - attempt(function() { fn.call(self, function() { self.run(fns, index + 1); }); }); - } else { - attempt(function() { fn.call(self); }); - self.run(fns, index + 1); + if (iterativeIndex >= length) { + this.onComplete(); } function attempt(fn) { diff --git a/src/core/Suite.js b/src/core/Suite.js index fdcdceef..5d080d6c 100644 --- a/src/core/Suite.js +++ b/src/core/Suite.js @@ -93,9 +93,7 @@ getJasmineRequireObj().Suite = function() { } function wrapChild(child) { - return function(done) { - child.execute(done); - }; + return function() { child.execute(); }; } };