From 76ca5ef6d401a763366192efcd2d9a9437e5b283 Mon Sep 17 00:00:00 2001 From: Sheel Choksi Date: Tue, 18 Feb 2014 19:58:07 -0800 Subject: [PATCH] Allow matcher custom failure messages to be a function By deferring the evaluation of these messages, we can avoid the expensive creation of them when in the majority use case (tests are passing) they are not needed. These failure messages were causing performance problems with larger objects needed to be pretty printed as discussed in #520 and brought up by @rdy. [fixes #65925900][fixes #520] --- lib/jasmine-core/jasmine.js | 83 ++++++++++--------- spec/core/ExpectationSpec.js | 34 ++++++++ spec/core/matchers/toBeNaNSpec.js | 2 +- .../core/matchers/toHaveBeenCalledWithSpec.js | 6 +- spec/core/matchers/toThrowErrorSpec.js | 22 ++--- spec/core/matchers/toThrowSpec.js | 10 +-- src/core/Expectation.js | 6 +- src/core/matchers/toBeNaN.js | 2 +- src/core/matchers/toHaveBeenCalledWith.js | 6 +- src/core/matchers/toThrow.js | 6 +- src/core/matchers/toThrowError.js | 63 +++++++------- 11 files changed, 142 insertions(+), 98 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index aa3340b7..d8ac0e20 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1201,7 +1201,11 @@ getJasmineRequireObj().Expectation = function() { args.unshift(name); message = this.util.buildFailureMessage.apply(null, args); } else { - message = result.message; + if (Object.prototype.toString.apply(result.message) === "[object Function]") { + message = result.message(); + } else { + message = result.message; + } } } @@ -2030,7 +2034,7 @@ getJasmineRequireObj().toBeNaN = function(j$) { if (result.pass) { result.message = "Expected actual not to be NaN."; } else { - result.message = "Expected " + j$.pp(actual) + " to be NaN."; + result.message = function() { return "Expected " + j$.pp(actual) + " to be NaN."; }; } return result; @@ -2168,15 +2172,15 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { } if (!actual.calls.any()) { - result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but it was never called."; + result.message = function() { return "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but it was never called."; }; return result; } if (util.contains(actual.calls.allArgs(), expectedArgs)) { result.pass = true; - result.message = "Expected spy " + actual.and.identity() + " not to have been called with " + j$.pp(expectedArgs) + " but it was."; + result.message = function() { return "Expected spy " + actual.and.identity() + " not to have been called with " + j$.pp(expectedArgs) + " but it was."; }; } else { - result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but actual calls were " + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + "."; + result.message = function() { return "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but actual calls were " + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + "."; }; } return result; @@ -2231,16 +2235,16 @@ getJasmineRequireObj().toThrow = function(j$) { if (arguments.length == 1) { result.pass = true; - result.message = "Expected function not to throw, but it threw " + j$.pp(thrown) + "."; + result.message = function() { return "Expected function not to throw, but it threw " + j$.pp(thrown) + "."; }; return result; } if (util.equals(thrown, expected)) { result.pass = true; - result.message = "Expected function not to throw " + j$.pp(expected) + "."; + result.message = function() { return "Expected function not to throw " + j$.pp(expected) + "."; }; } else { - result.message = "Expected function to throw " + j$.pp(expected) + ", but it threw " + j$.pp(thrown) + "."; + result.message = function() { return "Expected function to throw " + j$.pp(expected) + ", but it threw " + j$.pp(thrown) + "."; }; } return result; @@ -2256,6 +2260,8 @@ getJasmineRequireObj().toThrowError = function(j$) { return { compare: function(actual) { var threw = false, + pass = {pass: true}, + fail = {pass: false}, thrown, errorType, message, @@ -2277,15 +2283,18 @@ getJasmineRequireObj().toThrowError = function(j$) { } if (!threw) { - return fail("Expected function to throw an Error."); + fail.message = "Expected function to throw an Error."; + return fail; } if (!(thrown instanceof Error)) { - return fail("Expected function to throw an Error, but it threw " + thrown + "."); + fail.message = function() { return "Expected function to throw an Error, but it threw " + j$.pp(thrown) + "."; }; + return fail; } if (arguments.length == 1) { - return pass("Expected function not to throw an Error, but it threw " + fnNameFor(thrown) + "."); + pass.message = "Expected function not to throw an Error, but it threw " + fnNameFor(thrown) + "."; + return pass; } if (errorType) { @@ -2295,45 +2304,55 @@ getJasmineRequireObj().toThrowError = function(j$) { if (errorType && message) { if (thrown.constructor == errorType && util.equals(thrown.message, message)) { - return pass("Expected function not to throw " + name + " with message \"" + message + "\"."); + pass.message = function() { return "Expected function not to throw " + name + " with message " + j$.pp(message) + "."; }; + return pass; } else { - return fail("Expected function to throw " + name + " with message \"" + message + - "\", but it threw " + constructorName + " with message \"" + thrown.message + "\"."); + fail.message = function() { return "Expected function to throw " + name + " with message " + j$.pp(message) + + ", but it threw " + constructorName + " with message " + j$.pp(thrown.message) + "."; }; + return fail; } } if (errorType && regexp) { if (thrown.constructor == errorType && regexp.test(thrown.message)) { - return pass("Expected function not to throw " + name + " with message matching " + regexp + "."); + pass.message = function() { return "Expected function not to throw " + name + " with message matching " + j$.pp(regexp) + "."; }; + return pass; } else { - return fail("Expected function to throw " + name + " with message matching " + regexp + - ", but it threw " + constructorName + " with message \"" + thrown.message + "\"."); + fail.message = function() { return "Expected function to throw " + name + " with message matching " + j$.pp(regexp) + + ", but it threw " + constructorName + " with message " + j$.pp(thrown.message) + "."; }; + return fail; } } if (errorType) { if (thrown.constructor == errorType) { - return pass("Expected function not to throw " + name + "."); + pass.message = "Expected function not to throw " + name + "."; + return pass; } else { - return fail("Expected function to throw " + name + ", but it threw " + constructorName + "."); + fail.message = "Expected function to throw " + name + ", but it threw " + constructorName + "."; + return fail; } } if (message) { if (thrown.message == message) { - return pass("Expected function not to throw an exception with message " + j$.pp(message) + "."); + pass.message = function() { return "Expected function not to throw an exception with message " + j$.pp(message) + "."; }; + return pass; } else { - return fail("Expected function to throw an exception with message " + j$.pp(message) + - ", but it threw an exception with message " + j$.pp(thrown.message) + "."); + fail.message = function() { return "Expected function to throw an exception with message " + j$.pp(message) + + ", but it threw an exception with message " + j$.pp(thrown.message) + "."; }; + return fail; } } if (regexp) { if (regexp.test(thrown.message)) { - return pass("Expected function not to throw an exception with a message matching " + j$.pp(regexp) + "."); + pass.message = function() { return "Expected function not to throw an exception with a message matching " + j$.pp(regexp) + "."; }; + return pass; } else { - return fail("Expected function to throw an exception with a message matching " + j$.pp(regexp) + - ", but it threw an exception with message " + j$.pp(thrown.message) + "."); + fail.message = function() { return "Expected function to throw an exception with a message matching " + j$.pp(regexp) + + ", but it threw an exception with message " + j$.pp(thrown.message) + "."; }; + return fail; } } @@ -2341,20 +2360,6 @@ getJasmineRequireObj().toThrowError = function(j$) { return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; } - function pass(notMessage) { - return { - pass: true, - message: notMessage - }; - } - - function fail(message) { - return { - pass: false, - message: message - }; - } - function extractExpectedParams() { if (arguments.length == 1) { return; diff --git a/spec/core/ExpectationSpec.js b/spec/core/ExpectationSpec.js index 3c32011e..c5528aa1 100644 --- a/spec/core/ExpectationSpec.js +++ b/spec/core/ExpectationSpec.js @@ -193,6 +193,40 @@ describe("Expectation", function() { j$.Expectation.addMatchers(matchers); + expectation = new j$.Expectation({ + actual: "an actual", + addExpectationResult: addExpectationResult + }); + + expectation.toFoo("hello"); + + expect(addExpectationResult).toHaveBeenCalledWith(false, { + matcherName: "toFoo", + passed: false, + expected: "hello", + actual: "an actual", + message: "I am a custom message" + }); + }); + + it("reports a failing result with a custom fail message function to the spec when the comparison fails", function() { + var matchers = { + toFoo: function() { + return { + compare: function() { + return { + pass: false, + message: function() { return "I am a custom message"; } + }; + } + }; + } + }, + addExpectationResult = jasmine.createSpy("addExpectationResult"), + expectation; + + j$.Expectation.addMatchers(matchers); + expectation = new j$.Expectation({ matchers: matchers, actual: "an actual", diff --git a/spec/core/matchers/toBeNaNSpec.js b/spec/core/matchers/toBeNaNSpec.js index c0cbcc5d..4c82a0f7 100644 --- a/spec/core/matchers/toBeNaNSpec.js +++ b/spec/core/matchers/toBeNaNSpec.js @@ -32,6 +32,6 @@ describe("toBeNaN", function() { var matcher = j$.matchers.toBeNaN(), result = matcher.compare(0); - expect(result.message).toEqual("Expected 0 to be NaN."); + expect(result.message()).toEqual("Expected 0 to be NaN."); }); }); diff --git a/spec/core/matchers/toHaveBeenCalledWithSpec.js b/spec/core/matchers/toHaveBeenCalledWithSpec.js index 466682cd..1af0a76f 100644 --- a/spec/core/matchers/toHaveBeenCalledWithSpec.js +++ b/spec/core/matchers/toHaveBeenCalledWithSpec.js @@ -11,7 +11,7 @@ describe("toHaveBeenCalledWith", function() { result = matcher.compare(calledSpy, 'a', 'b'); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected spy called-spy not to have been called with [ 'a', 'b' ] but it was."); + expect(result.message()).toEqual("Expected spy called-spy not to have been called with [ 'a', 'b' ] but it was."); }); it("fails when the actual was not called", function() { @@ -24,7 +24,7 @@ describe("toHaveBeenCalledWith", function() { result = matcher.compare(uncalledSpy); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected spy uncalled spy to have been called with [ ] but it was never called."); + expect(result.message()).toEqual("Expected spy uncalled spy to have been called with [ ] but it was never called."); }); it("fails when the actual was called with different parameters", function() { @@ -40,7 +40,7 @@ describe("toHaveBeenCalledWith", function() { result = matcher.compare(calledSpy, 'a', 'b'); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected spy called spy to have been called with [ 'a', 'b' ] but actual calls were [ 'a' ], [ 'c', 'd' ]."); + expect(result.message()).toEqual("Expected spy called spy to have been called with [ 'a', 'b' ] but actual calls were [ 'a' ], [ 'c', 'd' ]."); }); it("throws an exception when the actual is not a spy", function() { diff --git a/spec/core/matchers/toThrowErrorSpec.js b/spec/core/matchers/toThrowErrorSpec.js index 9e55820e..8dc88dbd 100644 --- a/spec/core/matchers/toThrowErrorSpec.js +++ b/spec/core/matchers/toThrowErrorSpec.js @@ -62,7 +62,7 @@ describe("toThrowError", function() { result = matcher.compare(fn); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw an Error, but it threw 4."); + expect(result.message()).toEqual("Expected function to throw an Error, but it threw 4."); }); it("fails with the correct message if thrown is a falsy value", function() { @@ -74,7 +74,7 @@ describe("toThrowError", function() { result = matcher.compare(fn); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw an Error, but it threw undefined."); + expect(result.message()).toEqual("Expected function to throw an Error, but it threw undefined."); }); it("passes if thrown is a type of Error, but there is no expected error", function() { @@ -100,7 +100,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, "foo"); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw an exception with message 'foo'."); + expect(result.message()).toEqual("Expected function not to throw an exception with message 'foo'."); }); it("fails if thrown is an Error and the expected is not the same message", function() { @@ -113,7 +113,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, "bar"); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw an exception with message 'bar', but it threw an exception with message 'foo'."); + expect(result.message()).toEqual("Expected function to throw an exception with message 'bar', but it threw an exception with message 'foo'."); }); it("passes if thrown is an Error and the expected is a RegExp that matches the message", function() { @@ -126,7 +126,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, /long/); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw an exception with a message matching /long/."); + expect(result.message()).toEqual("Expected function not to throw an exception with a message matching /long/."); }); it("fails if thrown is an Error and the expected is a RegExp that does not match the message", function() { @@ -139,7 +139,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, /foo/); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw an exception with a message matching /foo/, but it threw an exception with message 'a long message'."); + expect(result.message()).toEqual("Expected function to throw an exception with a message matching /foo/, but it threw an exception with message 'a long message'."); }); it("passes if thrown is an Error and the expected the same Error", function() { @@ -207,7 +207,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, TypeError, "foo"); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw TypeError with message \"foo\"."); + expect(result.message()).toEqual("Expected function not to throw TypeError with message 'foo'."); }); it("passes if thrown is a custom error that takes arguments and it is equal to the expected custom error and message", function() { @@ -227,7 +227,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, CustomError, "foo"); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw CustomError with message \"foo\"."); + expect(result.message()).toEqual("Expected function not to throw CustomError with message 'foo'."); }); it("fails if thrown is a type of Error and the expected is a different Error", function() { @@ -243,7 +243,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, TypeError, "bar"); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw TypeError with message \"bar\", but it threw TypeError with message \"foo\"."); + expect(result.message()).toEqual("Expected function to throw TypeError with message 'bar', but it threw TypeError with message 'foo'."); }); it("passes if thrown is a type of Error and has the same type as the expected Error and the message matches the expected message", function() { @@ -259,7 +259,7 @@ describe("toThrowError", function() { result = matcher.compare(fn, TypeError, /foo/); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw TypeError with message matching /foo/."); + expect(result.message()).toEqual("Expected function not to throw TypeError with message matching /foo/."); }); it("fails if thrown is a type of Error and the expected is a different Error", function() { @@ -275,6 +275,6 @@ describe("toThrowError", function() { result = matcher.compare(fn, TypeError, /bar/); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw TypeError with message matching /bar/, but it threw TypeError with message \"foo\"."); + expect(result.message()).toEqual("Expected function to throw TypeError with message matching /bar/, but it threw TypeError with message 'foo'."); }); }); diff --git a/spec/core/matchers/toThrowSpec.js b/spec/core/matchers/toThrowSpec.js index 15af808c..33485628 100644 --- a/spec/core/matchers/toThrowSpec.js +++ b/spec/core/matchers/toThrowSpec.js @@ -34,7 +34,7 @@ describe("toThrow", function() { result = matcher.compare(fn); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw, but it threw 5."); + expect(result.message()).toEqual("Expected function not to throw, but it threw 5."); }); it("passes even if what is thrown is falsy", function() { @@ -46,7 +46,7 @@ describe("toThrow", function() { result = matcher.compare(fn); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw, but it threw undefined."); + expect(result.message()).toEqual("Expected function not to throw, but it threw undefined."); }); it("passes if what is thrown is equivalent to what is expected", function() { @@ -62,7 +62,7 @@ describe("toThrow", function() { result = matcher.compare(fn, 5); expect(result.pass).toBe(true); - expect(result.message).toEqual("Expected function not to throw 5."); + expect(result.message()).toEqual("Expected function not to throw 5."); }); it("fails if what is thrown is not equivalent to what is expected", function() { @@ -78,7 +78,7 @@ describe("toThrow", function() { result = matcher.compare(fn, "foo"); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw 'foo', but it threw 5."); + expect(result.message()).toEqual("Expected function to throw 'foo', but it threw 5."); }); it("fails if what is thrown is not equivalent to undefined", function() { @@ -94,6 +94,6 @@ describe("toThrow", function() { result = matcher.compare(fn, void 0); expect(result.pass).toBe(false); - expect(result.message).toEqual("Expected function to throw undefined, but it threw 5."); + expect(result.message()).toEqual("Expected function to throw undefined, but it threw 5."); }); }); diff --git a/src/core/Expectation.js b/src/core/Expectation.js index 3f82c09c..33b5c8e0 100644 --- a/src/core/Expectation.js +++ b/src/core/Expectation.js @@ -43,7 +43,11 @@ getJasmineRequireObj().Expectation = function() { args.unshift(name); message = this.util.buildFailureMessage.apply(null, args); } else { - message = result.message; + if (Object.prototype.toString.apply(result.message) === "[object Function]") { + message = result.message(); + } else { + message = result.message; + } } } diff --git a/src/core/matchers/toBeNaN.js b/src/core/matchers/toBeNaN.js index a8b0c270..cdf8ee65 100644 --- a/src/core/matchers/toBeNaN.js +++ b/src/core/matchers/toBeNaN.js @@ -10,7 +10,7 @@ getJasmineRequireObj().toBeNaN = function(j$) { if (result.pass) { result.message = "Expected actual not to be NaN."; } else { - result.message = "Expected " + j$.pp(actual) + " to be NaN."; + result.message = function() { return "Expected " + j$.pp(actual) + " to be NaN."; }; } return result; diff --git a/src/core/matchers/toHaveBeenCalledWith.js b/src/core/matchers/toHaveBeenCalledWith.js index da9ccf37..ca6db4c4 100644 --- a/src/core/matchers/toHaveBeenCalledWith.js +++ b/src/core/matchers/toHaveBeenCalledWith.js @@ -13,15 +13,15 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { } if (!actual.calls.any()) { - result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but it was never called."; + result.message = function() { return "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but it was never called."; }; return result; } if (util.contains(actual.calls.allArgs(), expectedArgs)) { result.pass = true; - result.message = "Expected spy " + actual.and.identity() + " not to have been called with " + j$.pp(expectedArgs) + " but it was."; + result.message = function() { return "Expected spy " + actual.and.identity() + " not to have been called with " + j$.pp(expectedArgs) + " but it was."; }; } else { - result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but actual calls were " + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + "."; + result.message = function() { return "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but actual calls were " + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + "."; }; } return result; diff --git a/src/core/matchers/toThrow.js b/src/core/matchers/toThrow.js index 4a2fa1dd..7b47a310 100644 --- a/src/core/matchers/toThrow.js +++ b/src/core/matchers/toThrow.js @@ -25,16 +25,16 @@ getJasmineRequireObj().toThrow = function(j$) { if (arguments.length == 1) { result.pass = true; - result.message = "Expected function not to throw, but it threw " + j$.pp(thrown) + "."; + result.message = function() { return "Expected function not to throw, but it threw " + j$.pp(thrown) + "."; }; return result; } if (util.equals(thrown, expected)) { result.pass = true; - result.message = "Expected function not to throw " + j$.pp(expected) + "."; + result.message = function() { return "Expected function not to throw " + j$.pp(expected) + "."; }; } else { - result.message = "Expected function to throw " + j$.pp(expected) + ", but it threw " + j$.pp(thrown) + "."; + result.message = function() { return "Expected function to throw " + j$.pp(expected) + ", but it threw " + j$.pp(thrown) + "."; }; } return result; diff --git a/src/core/matchers/toThrowError.js b/src/core/matchers/toThrowError.js index ca5a7df0..956dea07 100644 --- a/src/core/matchers/toThrowError.js +++ b/src/core/matchers/toThrowError.js @@ -3,6 +3,8 @@ getJasmineRequireObj().toThrowError = function(j$) { return { compare: function(actual) { var threw = false, + pass = {pass: true}, + fail = {pass: false}, thrown, errorType, message, @@ -24,15 +26,18 @@ getJasmineRequireObj().toThrowError = function(j$) { } if (!threw) { - return fail("Expected function to throw an Error."); + fail.message = "Expected function to throw an Error."; + return fail; } if (!(thrown instanceof Error)) { - return fail("Expected function to throw an Error, but it threw " + thrown + "."); + fail.message = function() { return "Expected function to throw an Error, but it threw " + j$.pp(thrown) + "."; }; + return fail; } if (arguments.length == 1) { - return pass("Expected function not to throw an Error, but it threw " + fnNameFor(thrown) + "."); + pass.message = "Expected function not to throw an Error, but it threw " + fnNameFor(thrown) + "."; + return pass; } if (errorType) { @@ -42,45 +47,55 @@ getJasmineRequireObj().toThrowError = function(j$) { if (errorType && message) { if (thrown.constructor == errorType && util.equals(thrown.message, message)) { - return pass("Expected function not to throw " + name + " with message \"" + message + "\"."); + pass.message = function() { return "Expected function not to throw " + name + " with message " + j$.pp(message) + "."; }; + return pass; } else { - return fail("Expected function to throw " + name + " with message \"" + message + - "\", but it threw " + constructorName + " with message \"" + thrown.message + "\"."); + fail.message = function() { return "Expected function to throw " + name + " with message " + j$.pp(message) + + ", but it threw " + constructorName + " with message " + j$.pp(thrown.message) + "."; }; + return fail; } } if (errorType && regexp) { if (thrown.constructor == errorType && regexp.test(thrown.message)) { - return pass("Expected function not to throw " + name + " with message matching " + regexp + "."); + pass.message = function() { return "Expected function not to throw " + name + " with message matching " + j$.pp(regexp) + "."; }; + return pass; } else { - return fail("Expected function to throw " + name + " with message matching " + regexp + - ", but it threw " + constructorName + " with message \"" + thrown.message + "\"."); + fail.message = function() { return "Expected function to throw " + name + " with message matching " + j$.pp(regexp) + + ", but it threw " + constructorName + " with message " + j$.pp(thrown.message) + "."; }; + return fail; } } if (errorType) { if (thrown.constructor == errorType) { - return pass("Expected function not to throw " + name + "."); + pass.message = "Expected function not to throw " + name + "."; + return pass; } else { - return fail("Expected function to throw " + name + ", but it threw " + constructorName + "."); + fail.message = "Expected function to throw " + name + ", but it threw " + constructorName + "."; + return fail; } } if (message) { if (thrown.message == message) { - return pass("Expected function not to throw an exception with message " + j$.pp(message) + "."); + pass.message = function() { return "Expected function not to throw an exception with message " + j$.pp(message) + "."; }; + return pass; } else { - return fail("Expected function to throw an exception with message " + j$.pp(message) + - ", but it threw an exception with message " + j$.pp(thrown.message) + "."); + fail.message = function() { return "Expected function to throw an exception with message " + j$.pp(message) + + ", but it threw an exception with message " + j$.pp(thrown.message) + "."; }; + return fail; } } if (regexp) { if (regexp.test(thrown.message)) { - return pass("Expected function not to throw an exception with a message matching " + j$.pp(regexp) + "."); + pass.message = function() { return "Expected function not to throw an exception with a message matching " + j$.pp(regexp) + "."; }; + return pass; } else { - return fail("Expected function to throw an exception with a message matching " + j$.pp(regexp) + - ", but it threw an exception with message " + j$.pp(thrown.message) + "."); + fail.message = function() { return "Expected function to throw an exception with a message matching " + j$.pp(regexp) + + ", but it threw an exception with message " + j$.pp(thrown.message) + "."; }; + return fail; } } @@ -88,20 +103,6 @@ getJasmineRequireObj().toThrowError = function(j$) { return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; } - function pass(notMessage) { - return { - pass: true, - message: notMessage - }; - } - - function fail(message) { - return { - pass: false, - message: message - }; - } - function extractExpectedParams() { if (arguments.length == 1) { return;