From 2385acedd8d55bf781595d79384fc7dccd054688 Mon Sep 17 00:00:00 2001 From: Alex Kwiatkowski Date: Sun, 15 Apr 2012 17:34:31 -0400 Subject: [PATCH] Add config option which stops jasmine from capturing exceptions in a test --- lib/jasmine-core/jasmine.js | 20 +++- spec/core/ExceptionsSpec.js | 216 ++++++++++++++++++++---------------- src/core/Block.js | 13 ++- src/core/base.js | 7 ++ 4 files changed, 153 insertions(+), 103 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 03bf89a0..c7d4eb55 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -39,6 +39,13 @@ jasmine.DEFAULT_UPDATE_INTERVAL = 250; */ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; +/** + * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite. + * Set to false to let the exception bubble up in the browser. + * + */ +jasmine.CATCH_EXCEPTIONS = true; + jasmine.getGlobal = function() { function getGlobal() { return this; @@ -1019,11 +1026,16 @@ jasmine.Block = function(env, func, spec) { this.spec = spec; }; -jasmine.Block.prototype.execute = function(onComplete) { - try { +jasmine.Block.prototype.execute = function(onComplete) { + if (!jasmine.CATCH_EXCEPTIONS) { this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); + } + else { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } } onComplete(); }; diff --git a/spec/core/ExceptionsSpec.js b/spec/core/ExceptionsSpec.js index fcd51eeb..315aa1bf 100644 --- a/spec/core/ExceptionsSpec.js +++ b/spec/core/ExceptionsSpec.js @@ -32,118 +32,144 @@ describe('Exceptions:', function() { expect(jasmine.util.formatException(sampleWebkitException)).toEqual(expected); }); - it('should handle exceptions thrown, but continue', function() { - var fakeTimer = new jasmine.FakeTimer(); - env.setTimeout = fakeTimer.setTimeout; - env.clearTimeout = fakeTimer.clearTimeout; - env.setInterval = fakeTimer.setInterval; - env.clearInterval = fakeTimer.clearInterval; - - //we run two exception tests to make sure we continue after throwing an exception - var suite = env.describe('Suite for handles exceptions', function () { - env.it('should be a test that fails because it throws an exception', function() { - throw new Error('fake error 1'); - }); - - env.it('should be another test that fails because it throws an exception', function() { - this.runs(function () { - throw new Error('fake error 2'); + describe('with break on exception', function() { + it('should not catch the exception', function() { + var suite = env.describe('suite for break on exceptions', function() { + env.it('should break when an exception is thrown', function() { + throw new Error('I should hit a breakpoint!'); }); - this.runs(function () { + }); + var runner = env.currentRunner(); + var dont_change = 'I will never change!'; + + var oldCatch = jasmine.CATCH_EXCEPTIONS; + jasmine.CATCH_EXCEPTIONS = false; + try { + suite.execute(); + dont_change = 'oops I changed'; + } + catch (e) {} + finally { + jasmine.CATCH_EXCEPTIONS = oldCatch; + } + + expect(dont_change).toEqual('I will never change!'); + }); + }); + + describe("with catch on exception", function() { + it('should handle exceptions thrown, but continue', function() { + var fakeTimer = new jasmine.FakeTimer(); + env.setTimeout = fakeTimer.setTimeout; + env.clearTimeout = fakeTimer.clearTimeout; + env.setInterval = fakeTimer.setInterval; + env.clearInterval = fakeTimer.clearInterval; + + //we run two exception tests to make sure we continue after throwing an exception + var suite = env.describe('Suite for handles exceptions', function () { + env.it('should be a test that fails because it throws an exception', function() { + throw new Error('fake error 1'); + }); + + env.it('should be another test that fails because it throws an exception', function() { + this.runs(function () { + throw new Error('fake error 2'); + }); + this.runs(function () { + this.expect(true).toEqual(true); + }); + }); + + env.it('should be a passing test that runs after exceptions are thrown', function() { + this.expect(true).toEqual(true); + }); + + env.it('should be another test that fails because it throws an exception after a wait', function() { + this.runs(function () { + var foo = 'foo'; + }); + this.waits(250); + this.runs(function () { + throw new Error('fake error 3'); + }); + }); + + env.it('should be a passing test that runs after exceptions are thrown from a async test', function() { this.expect(true).toEqual(true); }); }); - env.it('should be a passing test that runs after exceptions are thrown', function() { - this.expect(true).toEqual(true); - }); + var runner = env.currentRunner(); + suite.execute(); + fakeTimer.tick(2500); - env.it('should be another test that fails because it throws an exception after a wait', function() { - this.runs(function () { - var foo = 'foo'; - }); - this.waits(250); - this.runs(function () { - throw new Error('fake error 3'); - }); - }); + var suiteResults = suite.results(); + var specResults = suiteResults.getItems(); - env.it('should be a passing test that runs after exceptions are thrown from a async test', function() { - this.expect(true).toEqual(true); - }); + expect(suiteResults.passed()).toEqual(false); + // + expect(specResults.length).toEqual(5); + expect(specResults[0].passed()).toMatch(false); + var blockResults = specResults[0].getItems(); + expect(blockResults[0].passed()).toEqual(false); + expect(blockResults[0].message).toMatch(/fake error 1/); + + expect(specResults[1].passed()).toEqual(false); + blockResults = specResults[1].getItems(); + expect(blockResults[0].passed()).toEqual(false); + expect(blockResults[0].message).toMatch(/fake error 2/); + expect(blockResults[1].passed()).toEqual(true); + + expect(specResults[2].passed()).toEqual(true); + + expect(specResults[3].passed()).toEqual(false); + blockResults = specResults[3].getItems(); + expect(blockResults[0].message).toMatch(/fake error 3/); + + expect(specResults[4].passed()).toEqual(true); }); - var runner = env.currentRunner(); - suite.execute(); - fakeTimer.tick(2500); - - var suiteResults = suite.results(); - var specResults = suiteResults.getItems(); - - expect(suiteResults.passed()).toEqual(false); - // - expect(specResults.length).toEqual(5); - expect(specResults[0].passed()).toMatch(false); - var blockResults = specResults[0].getItems(); - expect(blockResults[0].passed()).toEqual(false); - expect(blockResults[0].message).toMatch(/fake error 1/); - - expect(specResults[1].passed()).toEqual(false); - blockResults = specResults[1].getItems(); - expect(blockResults[0].passed()).toEqual(false); - expect(blockResults[0].message).toMatch(/fake error 2/); - expect(blockResults[1].passed()).toEqual(true); - - expect(specResults[2].passed()).toEqual(true); - - expect(specResults[3].passed()).toEqual(false); - blockResults = specResults[3].getItems(); - expect(blockResults[0].message).toMatch(/fake error 3/); - - expect(specResults[4].passed()).toEqual(true); - }); - - - it("should handle exceptions thrown directly in top-level describe blocks and continue", function () { - var suite = env.describe("a top level describe block that throws an exception", function () { - env.it("is a test that should pass", function () { + it("should handle exceptions thrown directly in top-level describe blocks and continue", function () { + var suite = env.describe("a top level describe block that throws an exception", function () { + env.it("is a test that should pass", function () { this.expect(true).toEqual(true); - }); + }); - throw new Error("top level error"); - }); + throw new Error("top level error"); + }); - suite.execute(); - var suiteResults = suite.results(); - var specResults = suiteResults.getItems(); + suite.execute(); + var suiteResults = suite.results(); + var specResults = suiteResults.getItems(); - expect(suiteResults.passed()).toEqual(false); - expect(specResults.length).toEqual(2); + expect(suiteResults.passed()).toEqual(false); + expect(specResults.length).toEqual(2); - expect(specResults[1].description).toMatch(/encountered a declaration exception/); - }); + expect(specResults[1].description).toMatch(/encountered a declaration exception/); + }); - it("should handle exceptions thrown directly in nested describe blocks and continue", function () { - var suite = env.describe("a top level describe", function () { - env.describe("a mid-level describe that throws an exception", function () { - env.it("is a test that should pass", function () { - this.expect(true).toEqual(true); - }); + it("should handle exceptions thrown directly in nested describe blocks and continue", function () { + var suite = env.describe("a top level describe", function () { + env.describe("a mid-level describe that throws an exception", function () { + env.it("is a test that should pass", function () { + this.expect(true).toEqual(true); + }); - throw new Error("a mid-level error"); - }); - }); + throw new Error("a mid-level error"); + }); + }); - suite.execute(); - var suiteResults = suite.results(); - var specResults = suiteResults.getItems(); + suite.execute(); + var suiteResults = suite.results(); + var specResults = suiteResults.getItems(); - expect(suiteResults.passed()).toEqual(false); - expect(specResults.length).toEqual(1); + expect(suiteResults.passed()).toEqual(false); + expect(specResults.length).toEqual(1); - var nestedSpecResults = specResults[0].getItems(); + var nestedSpecResults = specResults[0].getItems(); - expect(nestedSpecResults.length).toEqual(2); - expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/); - }); -}); \ No newline at end of file + expect(nestedSpecResults.length).toEqual(2); + expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/); + }); + }); +}); diff --git a/src/core/Block.js b/src/core/Block.js index b24221e1..8085095d 100644 --- a/src/core/Block.js +++ b/src/core/Block.js @@ -12,11 +12,16 @@ jasmine.Block = function(env, func, spec) { this.spec = spec; }; -jasmine.Block.prototype.execute = function(onComplete) { - try { +jasmine.Block.prototype.execute = function(onComplete) { + if (!jasmine.CATCH_EXCEPTIONS) { this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); + } + else { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } } onComplete(); }; diff --git a/src/core/base.js b/src/core/base.js index 3a61b3d8..a4afea98 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -39,6 +39,13 @@ jasmine.DEFAULT_UPDATE_INTERVAL = 250; */ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; +/** + * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite. + * Set to false to let the exception bubble up in the browser. + * + */ +jasmine.CATCH_EXCEPTIONS = true; + jasmine.getGlobal = function() { function getGlobal() { return this;