From 60a5d60f4243d4353de58c4a68103e589943e64f Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 28 Sep 2010 20:43:50 -0700 Subject: [PATCH 1/5] Consolidate all waitsFor specs in the same describe block. --- spec/suites/SpecRunningSpec.js | 168 ++++++++++++++++----------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/spec/suites/SpecRunningSpec.js b/spec/suites/SpecRunningSpec.js index 289d9468..f4b4c65d 100644 --- a/spec/suites/SpecRunningSpec.js +++ b/spec/suites/SpecRunningSpec.js @@ -398,6 +398,90 @@ describe("jasmine spec running", function () { expect(timeoutSpec.results().getItems()[0].message).toEqual('timeout: timed out after 500 msec waiting for something to happen'); expect(subsequentSpecRan).toEqual(true); }); + + describe('with consecutive calls', function () { + var foo; + beforeEach(function () { + foo = 0; + }); + + it('exits immediately (does not stack) if the latchFunction times out', function () { + var reachedFirstWaitsFor = false; + var reachedSecondWaitsFor = false; + env.describe('suite that waits', function () { + env.it('should stack timeouts', function() { + this.waitsFor(500, function () { + reachedFirstWaitsFor = true; + return false; + }); + this.waitsFor(500, function () { + reachedSecondWaitsFor = true; + }); + this.runs(function () { + foo++; + }); + }); + }); + + expect(reachedFirstWaitsFor).toEqual(false); + env.execute(); + + expect(reachedFirstWaitsFor).toEqual(true); + expect(foo).toEqual(0); + expect(reachedSecondWaitsFor).toEqual(false); + fakeTimer.tick(500); + expect(reachedSecondWaitsFor).toEqual(false); + expect(foo).toEqual(0); + fakeTimer.tick(500); + expect(reachedSecondWaitsFor).toEqual(false); + expect(foo).toEqual(0); + }); + + it('stacks latchFunctions', function () { + var firstWaitsResult = false; + var secondWaitsResult = false; + var waitsSuite = env.describe('suite that waits', function () { + env.it('spec with waitsFors', function() { + this.waitsFor(600, function () { + fakeTimer.setTimeout(function () { + firstWaitsResult = true; + }, 300); + return firstWaitsResult; + }); + this.waitsFor(600, function () { + fakeTimer.setTimeout(function () { + secondWaitsResult = true; + }, 300); + return secondWaitsResult; + }); + this.runs(function () { + foo++; + }); + }); + }); + + expect(firstWaitsResult).toEqual(false); + expect(secondWaitsResult).toEqual(false); + waitsSuite.execute(); + + expect(firstWaitsResult).toEqual(false); + expect(secondWaitsResult).toEqual(false); + expect(foo).toEqual(0); + + fakeTimer.tick(300); + + expect(firstWaitsResult).toEqual(true); + expect(secondWaitsResult).toEqual(false); + expect(foo).toEqual(0); + + fakeTimer.tick(300); + + expect(firstWaitsResult).toEqual(true); + expect(secondWaitsResult).toEqual(true); + expect(foo).toEqual(1); + + }); + }); }); it("testSpecAfter", function() { @@ -579,90 +663,6 @@ describe("jasmine spec running", function () { expect(quux).toEqual(1); }); - describe('#waitsFor should allow consecutive calls', function () { - var foo; - beforeEach(function () { - foo = 0; - }); - - it('exits immediately (does not stack) if the latchFunction times out', function () { - var reachedFirstWaitsFor = false; - var reachedSecondWaitsFor = false; - env.describe('suite that waits', function () { - env.it('should stack timeouts', function() { - this.waitsFor(500, function () { - reachedFirstWaitsFor = true; - return false; - }); - this.waitsFor(500, function () { - reachedSecondWaitsFor = true; - }); - this.runs(function () { - foo++; - }); - }); - }); - - expect(reachedFirstWaitsFor).toEqual(false); - env.execute(); - - expect(reachedFirstWaitsFor).toEqual(true); - expect(foo).toEqual(0); - expect(reachedSecondWaitsFor).toEqual(false); - fakeTimer.tick(500); - expect(reachedSecondWaitsFor).toEqual(false); - expect(foo).toEqual(0); - fakeTimer.tick(500); - expect(reachedSecondWaitsFor).toEqual(false); - expect(foo).toEqual(0); - }); - - it('stacks latchFunctions', function () { - var firstWaitsResult = false; - var secondWaitsResult = false; - var waitsSuite = env.describe('suite that waits', function () { - env.it('spec with waitsFors', function() { - this.waitsFor(600, function () { - fakeTimer.setTimeout(function () { - firstWaitsResult = true; - }, 300); - return firstWaitsResult; - }); - this.waitsFor(600, function () { - fakeTimer.setTimeout(function () { - secondWaitsResult = true; - }, 300); - return secondWaitsResult; - }); - this.runs(function () { - foo++; - }); - }); - }); - - expect(firstWaitsResult).toEqual(false); - expect(secondWaitsResult).toEqual(false); - waitsSuite.execute(); - - expect(firstWaitsResult).toEqual(false); - expect(secondWaitsResult).toEqual(false); - expect(foo).toEqual(0); - - fakeTimer.tick(300); - - expect(firstWaitsResult).toEqual(true); - expect(secondWaitsResult).toEqual(false); - expect(foo).toEqual(0); - - fakeTimer.tick(300); - - expect(firstWaitsResult).toEqual(true); - expect(secondWaitsResult).toEqual(true); - expect(foo).toEqual(1); - - }); - }); - it("#beforeEach should be able to eval runs and waits blocks", function () { var foo = 0; var bar = 0; From a8b0a0ee4f0fe5fa9fdb6099433306736e2d38fa Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 29 Sep 2010 08:19:43 -0700 Subject: [PATCH 2/5] Test that afterEach is called after a failing spec. --- spec/suites/RunnerSpec.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/suites/RunnerSpec.js b/spec/suites/RunnerSpec.js index 3f66aaa5..090a15ea 100644 --- a/spec/suites/RunnerSpec.js +++ b/spec/suites/RunnerSpec.js @@ -105,6 +105,19 @@ describe('RunnerTest', function() { expect(runnerResults.totalCount).toEqual(3); expect(runnerResults.passedCount).toEqual(3); }); + + it('should run after a failing spec', function () { + var afterEach = jasmine.createSpy(); + env.afterEach(afterEach); + + env.describe('suite', function () { + env.it('fails', function () { + this.explodes(); + }); + }).execute(); + + expect(afterEach).toHaveBeenCalled(); + }); }); From dbcabd397e44cb34ae6ab8dce686395178d78b79 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 29 Sep 2010 08:25:06 -0700 Subject: [PATCH 3/5] Test that show that afterEach and after are not being called when a waitsFor times out. --- spec/suites/SpecRunningSpec.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/spec/suites/SpecRunningSpec.js b/spec/suites/SpecRunningSpec.js index f4b4c65d..a52558f0 100644 --- a/spec/suites/SpecRunningSpec.js +++ b/spec/suites/SpecRunningSpec.js @@ -399,6 +399,39 @@ describe("jasmine spec running", function () { expect(subsequentSpecRan).toEqual(true); }); + it("runs afterEach after timing out", function() { + var afterEach = jasmine.createSpy('afterEach'); + + env.describe('foo', function () { + env.afterEach(afterEach); + + env.it('waitsFor', function () { + this.waitsFor(100, function() { + return false; + }); + }); + }).execute(); + + fakeTimer.tick(500); + expect(afterEach).toHaveBeenCalled(); + }); + + it("runs single-spec after functions after timing out", function() { + var after = jasmine.createSpy('after'); + + env.describe('foo', function () { + env.it('waitsFor', function () { + this.after(after); + this.waitsFor(100, function() { + return false; + }); + }); + }).execute(); + + fakeTimer.tick(500); + expect(after).toHaveBeenCalled(); + }); + describe('with consecutive calls', function () { var foo; beforeEach(function () { From 1c2e50d244c07c16b217cdbc26ee17c27ea24033 Mon Sep 17 00:00:00 2001 From: rgould Date: Tue, 24 Jul 2012 18:01:21 -0400 Subject: [PATCH 4/5] Add 'ensured' blocks to the queue. This blocks will be run even when a preceeding block sets the abort flag. This is so that we can support afterEach calls running when the spec fails due to a timeout. --- src/core/Queue.js | 27 +++++++++++++++++++++++---- src/core/Spec.js | 8 ++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/core/Queue.js b/src/core/Queue.js index 065408c2..d4cd5ba7 100644 --- a/src/core/Queue.js +++ b/src/core/Queue.js @@ -1,5 +1,9 @@ jasmine.Queue = function(env) { this.env = env; + + // parallel to blocks. each true value in this array means the block will + // get executed even if we abort + this.ensured = []; this.blocks = []; this.running = false; this.index = 0; @@ -7,15 +11,30 @@ jasmine.Queue = function(env) { this.abort = false; }; -jasmine.Queue.prototype.addBefore = function(block) { +jasmine.Queue.prototype.addBefore = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + this.blocks.unshift(block); + this.ensured.unshift(ensure); }; -jasmine.Queue.prototype.add = function(block) { +jasmine.Queue.prototype.add = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + this.blocks.push(block); + this.ensured.push(ensure); }; -jasmine.Queue.prototype.insertNext = function(block) { +jasmine.Queue.prototype.insertNext = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + + this.ensured.splice((this.index + this.offset + 1), 0, ensure); this.blocks.splice((this.index + this.offset + 1), 0, block); this.offset++; }; @@ -39,7 +58,7 @@ jasmine.Queue.prototype.next_ = function() { while (goAgain) { goAgain = false; - if (self.index < self.blocks.length && !this.abort) { + if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) { var calledSynchronously = true; var completedSynchronously = false; diff --git a/src/core/Spec.js b/src/core/Spec.js index 972ccfde..469345b4 100644 --- a/src/core/Spec.js +++ b/src/core/Spec.js @@ -154,7 +154,7 @@ jasmine.Spec.prototype.finish = function(onComplete) { jasmine.Spec.prototype.after = function(doAfter) { if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); + this.queue.add(new jasmine.Block(this.env, doAfter, this), true); } else { this.afterCallbacks.unshift(doAfter); } @@ -192,15 +192,15 @@ jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); } for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); + this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true); } for (suite = this.suite; suite; suite = suite.parentSuite) { for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); + this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true); } } for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true); } }; From ddd48f2c889b88b225c18fbbfc7fdb2ef633b988 Mon Sep 17 00:00:00 2001 From: rgould Date: Tue, 24 Jul 2012 18:37:00 -0400 Subject: [PATCH 5/5] Regenerate jasmine.js after adding ensured support. --- lib/jasmine-core/jasmine.js | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 6bac2236..7dfa7d9f 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1964,6 +1964,10 @@ jasmine.StringPrettyPrinter.prototype.append = function(value) { }; jasmine.Queue = function(env) { this.env = env; + + // parallel to blocks. each true value in this array means the block will + // get executed even if we abort + this.ensured = []; this.blocks = []; this.running = false; this.index = 0; @@ -1971,15 +1975,30 @@ jasmine.Queue = function(env) { this.abort = false; }; -jasmine.Queue.prototype.addBefore = function(block) { +jasmine.Queue.prototype.addBefore = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + this.blocks.unshift(block); + this.ensured.unshift(ensure); }; -jasmine.Queue.prototype.add = function(block) { +jasmine.Queue.prototype.add = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + this.blocks.push(block); + this.ensured.push(ensure); }; -jasmine.Queue.prototype.insertNext = function(block) { +jasmine.Queue.prototype.insertNext = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + + this.ensured.splice((this.index + this.offset + 1), 0, ensure); this.blocks.splice((this.index + this.offset + 1), 0, block); this.offset++; }; @@ -2003,7 +2022,7 @@ jasmine.Queue.prototype.next_ = function() { while (goAgain) { goAgain = false; - if (self.index < self.blocks.length && !this.abort) { + if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) { var calledSynchronously = true; var completedSynchronously = false; @@ -2294,7 +2313,7 @@ jasmine.Spec.prototype.finish = function(onComplete) { jasmine.Spec.prototype.after = function(doAfter) { if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); + this.queue.add(new jasmine.Block(this.env, doAfter, this), true); } else { this.afterCallbacks.unshift(doAfter); } @@ -2332,15 +2351,15 @@ jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); } for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); + this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true); } for (suite = this.suite; suite; suite = suite.parentSuite) { for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); + this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true); } } for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true); } };