Allow use of a predicate function to validate thrown exceptions
[Finishes #20622765]
This commit is contained in:
@@ -3734,13 +3734,16 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
|||||||
throw new Error(getErrorMsg('Expected error type is not an Error.'));
|
throw new Error(getErrorMsg('Expected error type is not an Error.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return conditionalMatcher(expected, errorType);
|
return exactMatcher(expected, errorType);
|
||||||
} else if (arguments[1]) {
|
} else if (arguments[1]) {
|
||||||
expected = arguments[1];
|
expected = arguments[1];
|
||||||
|
|
||||||
if (isAnErrorType(arguments[1])) {
|
if (isAnErrorType(arguments[1])) {
|
||||||
return conditionalMatcher(null, arguments[1]);
|
return exactMatcher(null, arguments[1]);
|
||||||
|
} else if (j$.isFunction_(arguments[1])) {
|
||||||
|
return predicateMatcher(arguments[1]);
|
||||||
} else {
|
} else {
|
||||||
return conditionalMatcher(arguments[1], null);
|
return exactMatcher(arguments[1], null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return anyMatcher();
|
return anyMatcher();
|
||||||
@@ -3755,12 +3758,30 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function conditionalMatcher(expected, errorType) {
|
function predicateMatcher(predicate) {
|
||||||
|
return {
|
||||||
|
match: function(thrown) {
|
||||||
|
if (predicate(thrown)) {
|
||||||
|
return pass(function() {
|
||||||
|
return 'Expected function not to throw an exception matching a predicate.';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return fail(function() {
|
||||||
|
return 'Expected function to throw an exception matching a predicate, ' +
|
||||||
|
'but it threw ' + j$.fnNameFor(thrown.constructor) + ' with message ' +
|
||||||
|
j$.pp(thrown.message) + '.';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function exactMatcher(expected, errorType) {
|
||||||
if (expected && !isStringOrRegExp(expected)) {
|
if (expected && !isStringOrRegExp(expected)) {
|
||||||
if (errorType) {
|
if (errorType) {
|
||||||
throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
|
throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(getErrorMsg('Expected is not an Error, string, or RegExp.'));
|
throw new Error(getErrorMsg('Expected is not an Error, string, RegExp, or Function.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ describe("toThrowError", function() {
|
|||||||
}).toThrowError(/Actual is not a Function/);
|
}).toThrowError(/Actual is not a Function/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("throws an error when the expected is not an Error, string, or RegExp", function() {
|
it("throws an error when the expected is not an Error, string, RegExp, or function", function() {
|
||||||
var matcher = jasmineUnderTest.matchers.toThrowError(),
|
var matcher = jasmineUnderTest.matchers.toThrowError(),
|
||||||
fn = function() {
|
fn = function() {
|
||||||
throw new Error("foo");
|
throw new Error("foo");
|
||||||
@@ -15,7 +15,7 @@ describe("toThrowError", function() {
|
|||||||
|
|
||||||
expect(function() {
|
expect(function() {
|
||||||
matcher.compare(fn, 1);
|
matcher.compare(fn, 1);
|
||||||
}).toThrowError(/Expected is not an Error, string, or RegExp./);
|
}).toThrowError(/Expected is not an Error, string, RegExp, or Function./);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("throws an error when the expected error type is not an Error", function() {
|
it("throws an error when the expected error type is not an Error", function() {
|
||||||
@@ -312,4 +312,32 @@ describe("toThrowError", function() {
|
|||||||
expect(result.pass).toBe(false);
|
expect(result.pass).toBe(false);
|
||||||
expect(result.message()).toEqual("Expected function to throw TypeError with a message matching /bar/, but it threw TypeError with message 'foo'.");
|
expect(result.message()).toEqual("Expected function to throw TypeError with a message matching /bar/, but it threw TypeError with message 'foo'.");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("passes if the argument is a function that returns true when called with the error", function() {
|
||||||
|
var matcher = jasmineUnderTest.matchers.toThrowError(),
|
||||||
|
predicate = function(e) { return e.message === "nope" },
|
||||||
|
fn = function() {
|
||||||
|
throw new TypeError("nope");
|
||||||
|
},
|
||||||
|
result;
|
||||||
|
|
||||||
|
result = matcher.compare(fn, predicate);
|
||||||
|
|
||||||
|
expect(result.pass).toBe(true);
|
||||||
|
expect(result.message()).toEqual("Expected function not to throw an exception matching a predicate.");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fails if the argument is a function that returns false when called with the error", function() {
|
||||||
|
var matcher = jasmineUnderTest.matchers.toThrowError(),
|
||||||
|
predicate = function(e) { return e.message === "oh no" },
|
||||||
|
fn = function() {
|
||||||
|
throw new TypeError("nope");
|
||||||
|
},
|
||||||
|
result;
|
||||||
|
|
||||||
|
result = matcher.compare(fn, predicate);
|
||||||
|
|
||||||
|
expect(result.pass).toBe(false);
|
||||||
|
expect(result.message()).toEqual("Expected function to throw an exception matching a predicate, but it threw TypeError with message 'nope'.");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -50,13 +50,16 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
|||||||
throw new Error(getErrorMsg('Expected error type is not an Error.'));
|
throw new Error(getErrorMsg('Expected error type is not an Error.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return conditionalMatcher(expected, errorType);
|
return exactMatcher(expected, errorType);
|
||||||
} else if (arguments[1]) {
|
} else if (arguments[1]) {
|
||||||
expected = arguments[1];
|
expected = arguments[1];
|
||||||
|
|
||||||
if (isAnErrorType(arguments[1])) {
|
if (isAnErrorType(arguments[1])) {
|
||||||
return conditionalMatcher(null, arguments[1]);
|
return exactMatcher(null, arguments[1]);
|
||||||
|
} else if (j$.isFunction_(arguments[1])) {
|
||||||
|
return predicateMatcher(arguments[1]);
|
||||||
} else {
|
} else {
|
||||||
return conditionalMatcher(arguments[1], null);
|
return exactMatcher(arguments[1], null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return anyMatcher();
|
return anyMatcher();
|
||||||
@@ -71,12 +74,30 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function conditionalMatcher(expected, errorType) {
|
function predicateMatcher(predicate) {
|
||||||
|
return {
|
||||||
|
match: function(thrown) {
|
||||||
|
if (predicate(thrown)) {
|
||||||
|
return pass(function() {
|
||||||
|
return 'Expected function not to throw an exception matching a predicate.';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return fail(function() {
|
||||||
|
return 'Expected function to throw an exception matching a predicate, ' +
|
||||||
|
'but it threw ' + j$.fnNameFor(thrown.constructor) + ' with message ' +
|
||||||
|
j$.pp(thrown.message) + '.';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function exactMatcher(expected, errorType) {
|
||||||
if (expected && !isStringOrRegExp(expected)) {
|
if (expected && !isStringOrRegExp(expected)) {
|
||||||
if (errorType) {
|
if (errorType) {
|
||||||
throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
|
throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(getErrorMsg('Expected is not an Error, string, or RegExp.'));
|
throw new Error(getErrorMsg('Expected is not an Error, string, RegExp, or Function.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user