Avoid instantiating passed in errorType in toThrowError

since the passed in errorType could be a custom user function,
we instead detect if its an instanceof Error by using a Surrogate
(inspired by Backbone's use of surrogacy)
This commit is contained in:
Sheel Choksi
2013-06-03 21:05:13 -07:00
parent fbb9f53524
commit 7055d95584
2 changed files with 53 additions and 3 deletions

View File

@@ -158,6 +158,26 @@ describe("toThrowError", function() {
expect(result.message).toEqual("Expected function not to throw Error.");
});
it("passes if thrown is a custom error that takes arguments and the expected is the same error", function() {
var util = {
equals: j$.createSpy('delegated-equal').andReturn(true)
},
matcher = j$.matchers.toThrowError(util),
CustomError = function CustomError(arg) { arg.x },
fn = function() {
throw new CustomError({ x: 1 });
},
result;
CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;
result = matcher.compare(fn, CustomError);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw CustomError.");
});
it("fails if thrown is an Error and the expected is a different Error", function() {
var util = {
equals: j$.createSpy('delegated-equal').andReturn(false)
@@ -190,6 +210,26 @@ describe("toThrowError", function() {
expect(result.message).toEqual("Expected function not to throw Error 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() {
var util = {
equals: j$.createSpy('delegated-equal').andReturn(true)
},
matcher = j$.matchers.toThrowError(util),
CustomError = function CustomError(arg) { this.message = arg.message },
fn = function() {
throw new CustomError({message: "foo"});
},
result;
CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;
result = matcher.compare(fn, CustomError, "foo");
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw Error with message \"foo\".");
});
it("fails if thrown is an Error and the expected is a different Error", function() {
var util = {
equals: j$.createSpy('delegated-equal').andReturn(false)

View File

@@ -34,7 +34,7 @@ getJasmineRequireObj().toThrowError = function() {
}
if (errorType && message) {
if (util.equals(thrown, new errorType(message))) {
if (thrown.constructor == errorType && util.equals(thrown.message, message)) {
return pass("Expected function not to throw Error with message \"" + message + "\".");
} else {
return fail("Expected function to throw Error with message \"" + message + "\".");
@@ -99,7 +99,7 @@ getJasmineRequireObj().toThrowError = function() {
regexp = expected;
} else if (typeof expected == "string") {
message = expected;
} else if (typeof expected == "function" && new expected() instanceof Error) {
} else if (checkForAnErrorType(expected)) {
errorType = expected;
}
@@ -107,7 +107,7 @@ getJasmineRequireObj().toThrowError = function() {
throw new Error("Expected is not an Error, string, or RegExp.");
}
} else {
if (typeof arguments[1] == "function" && new arguments[1]() instanceof Error) {
if (checkForAnErrorType(arguments[1])) {
errorType = arguments[1];
} else {
throw new Error("Expected error type is not an Error.");
@@ -122,6 +122,16 @@ getJasmineRequireObj().toThrowError = function() {
}
}
}
function checkForAnErrorType(type) {
if (typeof expected == "function") {
return false;
}
var Surrogate = function() {};
Surrogate.prototype = type.prototype;
return (new Surrogate()) instanceof Error;
};
}
};
}