From 34b479a1a4e2f5c6ed822b771b54c4210706d0c5 Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Sat, 10 Oct 2009 10:20:56 -0700 Subject: [PATCH 1/7] Revert "Removed jasmine spec HTML runner (easier to use Rake tasks)" Let's keep it around though so we can run tests without Ruby, eh? This reverts commit e33ecf3665a6fc7cc1b70406248f9ca7979f00ae. --- spec/runner.html | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 spec/runner.html diff --git a/spec/runner.html b/spec/runner.html new file mode 100644 index 00000000..b6dac934 --- /dev/null +++ b/spec/runner.html @@ -0,0 +1,63 @@ + + + + Jasmine Test Runner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From f9b3eff5abf96436bcf5493eaa0707b3af15de10 Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Sat, 10 Oct 2009 10:28:19 -0700 Subject: [PATCH 2/7] Got standalone HTML test page working again. --- spec/runner.html | 63 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/spec/runner.html b/spec/runner.html index b6dac934..77ff7f89 100644 --- a/spec/runner.html +++ b/spec/runner.html @@ -8,36 +8,63 @@ + + + + - - - + - - - + + + + From d27684d2800d797452117b504ca28673934157c4 Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Mon, 12 Oct 2009 17:15:57 -0500 Subject: [PATCH 3/7] Oops, only report results once. --- spec/runner.html | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/spec/runner.html b/spec/runner.html index 77ff7f89..6c02a62e 100644 --- a/spec/runner.html +++ b/spec/runner.html @@ -71,20 +71,5 @@ - - - \ No newline at end of file From e1ebc1e692f7f01a60062dc845dbb49a7d91a497 Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Mon, 12 Oct 2009 17:22:00 -0500 Subject: [PATCH 4/7] Refactor Queue.js. --- src/Queue.js | 61 ++++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/src/Queue.js b/src/Queue.js index 27d3737b..01ebd10b 100644 --- a/src/Queue.js +++ b/src/Queue.js @@ -20,49 +20,40 @@ jasmine.Queue.prototype.insertNext = function (block) { }; jasmine.Queue.prototype.start = function(onComplete) { - var self = this; - self.running = true; - self.onComplete = onComplete; - if (self.blocks[0]) { - self.blocks[0].execute(function () { - self._next(); - }); - } else { - self.finish(); - } + this.running = true; + this.onComplete = onComplete; + this.next_(); }; jasmine.Queue.prototype.isRunning = function () { return this.running; }; -jasmine.Queue.prototype._next = function () { +var nestLevel = 0; + +jasmine.Queue.prototype.next_ = function () { var self = this; - var doNext = function () { - self.offset = 0; - self.index++; - if (self.index < self.blocks.length) { - self.blocks[self.index].execute(function () { - self._next(); - }); - } else { - self.finish(); - } - }; - var now = new Date().getTime(); - if (this.env.updateInterval && now - this.env.lastUpdate > this.env.updateInterval) { - this.env.lastUpdate = now; - this.env.setTimeout(doNext, 0); + if (self.index < self.blocks.length) { + self.blocks[self.index].execute(function () { + var doNext = function () { + self.offset = 0; + self.index++; + self.next_(); + }; + + var now = new Date().getTime(); + if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { + self.env.lastUpdate = now; + self.env.setTimeout(doNext, 0); + } else { + doNext(); + } + }); } else { - doNext(); - } - -}; - -jasmine.Queue.prototype.finish = function () { - this.running = false; - if (this.onComplete) { - this.onComplete(); + self.running = false; + if (self.onComplete) { + self.onComplete(); + } } }; From a3ed49a5ed44c6fae01b3f059cb7e3a64e445f4a Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Mon, 12 Oct 2009 21:02:50 -0500 Subject: [PATCH 5/7] Refactor. --- src/Queue.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Queue.js b/src/Queue.js index 01ebd10b..061c222c 100644 --- a/src/Queue.js +++ b/src/Queue.js @@ -6,7 +6,7 @@ jasmine.Queue = function(env) { this.offset = 0; }; -jasmine.Queue.prototype.addBefore = function (block) { +jasmine.Queue.prototype.addBefore = function(block) { this.blocks.unshift(block); }; @@ -14,7 +14,7 @@ jasmine.Queue.prototype.add = function(block) { this.blocks.push(block); }; -jasmine.Queue.prototype.insertNext = function (block) { +jasmine.Queue.prototype.insertNext = function(block) { this.blocks.splice((this.index + this.offset + 1), 0, block); this.offset++; }; @@ -25,28 +25,27 @@ jasmine.Queue.prototype.start = function(onComplete) { this.next_(); }; -jasmine.Queue.prototype.isRunning = function () { +jasmine.Queue.prototype.isRunning = function() { return this.running; }; var nestLevel = 0; -jasmine.Queue.prototype.next_ = function () { +jasmine.Queue.prototype.next_ = function() { var self = this; if (self.index < self.blocks.length) { self.blocks[self.index].execute(function () { - var doNext = function () { - self.offset = 0; - self.index++; - self.next_(); - }; + 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(doNext, 0); + self.env.setTimeout(function() { + self.next_(); + }, 0); } else { - doNext(); + self.next_(); } }); } else { @@ -57,7 +56,7 @@ jasmine.Queue.prototype.next_ = function () { } }; -jasmine.Queue.prototype.results = function () { +jasmine.Queue.prototype.results = function() { var results = new jasmine.NestedResults(); for (var i = 0; i < this.blocks.length; i++) { if (this.blocks[i].results) { From b7549196daa287b421bcea1ab547ca0b07f561e7 Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Mon, 12 Oct 2009 21:23:57 -0500 Subject: [PATCH 6/7] Blocks which complete synchronously have the completion de-nested. Big speed improvement, not quite sure why yet. --- src/Queue.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Queue.js b/src/Queue.js index 061c222c..18300d30 100644 --- a/src/Queue.js +++ b/src/Queue.js @@ -29,12 +29,20 @@ jasmine.Queue.prototype.isRunning = function() { return this.running; }; -var nestLevel = 0; +jasmine.Queue.UNROLL = true; jasmine.Queue.prototype.next_ = function() { var self = this; if (self.index < self.blocks.length) { - self.blocks[self.index].execute(function () { + var calledSynchronously = true; + var completedSynchronously = false; + + var onComplete = function () { + if (jasmine.Queue.UNROLL && calledSynchronously) { + completedSynchronously = true; + return; + } + self.offset = 0; self.index++; @@ -47,7 +55,13 @@ jasmine.Queue.prototype.next_ = function() { } else { self.next_(); } - }); + }; + self.blocks[self.index].execute(onComplete); + + calledSynchronously = false; + if (completedSynchronously) { + onComplete(); + } } else { self.running = false; if (self.onComplete) { From 5659a1e79eab776dceae58a54d71884b10b17e8d Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Mon, 12 Oct 2009 23:09:51 -0500 Subject: [PATCH 7/7] jasmine.Queue iterates by looping rather than recursing, so stack overflows should be less likely. --- spec/runner.html | 1 + spec/suites/QueueSpec.js | 23 +++++++++++++ src/Queue.js | 73 +++++++++++++++++++++++----------------- 3 files changed, 66 insertions(+), 31 deletions(-) create mode 100644 spec/suites/QueueSpec.js diff --git a/spec/runner.html b/spec/runner.html index 6c02a62e..f963bb46 100644 --- a/spec/runner.html +++ b/spec/runner.html @@ -39,6 +39,7 @@ 'suites/ExceptionsSpec.js', 'suites/TrivialReporterSpec.js', 'suites/MatchersSpec.js', + 'suites/QueueSpec.js', 'suites/ReporterSpec.js', 'suites/MultiReporterSpec.js', 'suites/PrettyPrintSpec.js', diff --git a/spec/suites/QueueSpec.js b/spec/suites/QueueSpec.js new file mode 100644 index 00000000..59a70f39 --- /dev/null +++ b/spec/suites/QueueSpec.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); + }); +}); \ No newline at end of file diff --git a/src/Queue.js b/src/Queue.js index 18300d30..c3e064a9 100644 --- a/src/Queue.js +++ b/src/Queue.js @@ -29,43 +29,54 @@ jasmine.Queue.prototype.isRunning = function() { return this.running; }; -jasmine.Queue.UNROLL = true; +jasmine.Queue.LOOP_DONT_RECURSE = true; jasmine.Queue.prototype.next_ = function() { var self = this; - if (self.index < self.blocks.length) { - var calledSynchronously = true; - var completedSynchronously = false; + var goAgain = true; - var onComplete = function () { - if (jasmine.Queue.UNROLL && calledSynchronously) { - completedSynchronously = true; - return; + while (goAgain) { + goAgain = false; + + 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; - 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 { - self.next_(); + + } else { + self.running = false; + if (self.onComplete) { + self.onComplete(); } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); } } };