167 lines
4.8 KiB
JavaScript
167 lines
4.8 KiB
JavaScript
getJasmineRequireObj().toThrowError = function(j$) {
|
|
|
|
var getErrorMsg = j$.formatErrorMsg('<toThrowError>', 'expect(function() {<expectation>}).toThrowError(<ErrorConstructor>, <message>)');
|
|
|
|
/**
|
|
* {@link expect} a function to `throw` an `Error`.
|
|
* @function
|
|
* @name matchers#toThrowError
|
|
* @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used.
|
|
* @param {RegExp|String} [message] - The message that should be set on the thrown `Error`
|
|
* @example
|
|
* expect(function() { return 'things'; }).toThrowError(MyCustomError, 'message');
|
|
* expect(function() { return 'things'; }).toThrowError(MyCustomError, /bar/);
|
|
* expect(function() { return 'stuff'; }).toThrowError(MyCustomError);
|
|
* expect(function() { return 'other'; }).toThrowError(/foo/);
|
|
* expect(function() { return 'other'; }).toThrowError();
|
|
*/
|
|
function toThrowError () {
|
|
return {
|
|
compare: function(actual) {
|
|
var errorMatcher = getMatcher.apply(null, arguments),
|
|
thrown;
|
|
|
|
if (typeof actual != 'function') {
|
|
throw new Error(getErrorMsg('Actual is not a Function'));
|
|
}
|
|
|
|
try {
|
|
actual();
|
|
return fail('Expected function to throw an Error.');
|
|
} catch (e) {
|
|
thrown = e;
|
|
}
|
|
|
|
if (!j$.isError_(thrown)) {
|
|
return fail(function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; });
|
|
}
|
|
|
|
return errorMatcher.match(thrown);
|
|
}
|
|
};
|
|
|
|
function getMatcher() {
|
|
var expected, errorType;
|
|
|
|
if (arguments[2]) {
|
|
errorType = arguments[1];
|
|
expected = arguments[2];
|
|
if (!isAnErrorType(errorType)) {
|
|
throw new Error(getErrorMsg('Expected error type is not an Error.'));
|
|
}
|
|
|
|
return exactMatcher(expected, errorType);
|
|
} else if (arguments[1]) {
|
|
expected = arguments[1];
|
|
|
|
if (isAnErrorType(arguments[1])) {
|
|
return exactMatcher(null, arguments[1]);
|
|
} else {
|
|
return exactMatcher(arguments[1], null);
|
|
}
|
|
} else {
|
|
return anyMatcher();
|
|
}
|
|
}
|
|
|
|
function anyMatcher() {
|
|
return {
|
|
match: function(error) {
|
|
return pass('Expected function not to throw an Error, but it threw ' + j$.fnNameFor(error) + '.');
|
|
}
|
|
};
|
|
}
|
|
|
|
function exactMatcher(expected, errorType) {
|
|
if (expected && !isStringOrRegExp(expected)) {
|
|
if (errorType) {
|
|
throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
|
|
} else {
|
|
throw new Error(getErrorMsg('Expected is not an Error, string, or RegExp.'));
|
|
}
|
|
}
|
|
|
|
function messageMatch(message) {
|
|
if (typeof expected == 'string') {
|
|
return expected == message;
|
|
} else {
|
|
return expected.test(message);
|
|
}
|
|
}
|
|
|
|
var errorTypeDescription = errorType ? j$.fnNameFor(errorType) : 'an exception';
|
|
|
|
function thrownDescription(thrown) {
|
|
var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception',
|
|
thrownMessage = '';
|
|
|
|
if (expected) {
|
|
thrownMessage = ' with message ' + j$.pp(thrown.message);
|
|
}
|
|
|
|
return thrownName + thrownMessage;
|
|
}
|
|
|
|
function messageDescription() {
|
|
if (expected === null) {
|
|
return '';
|
|
} else if (expected instanceof RegExp) {
|
|
return ' with a message matching ' + j$.pp(expected);
|
|
} else {
|
|
return ' with message ' + j$.pp(expected);
|
|
}
|
|
}
|
|
|
|
function matches(error) {
|
|
return (errorType === null || error instanceof errorType) &&
|
|
(expected === null || messageMatch(error.message));
|
|
}
|
|
|
|
return {
|
|
match: function(thrown) {
|
|
if (matches(thrown)) {
|
|
return pass(function() {
|
|
return 'Expected function not to throw ' + errorTypeDescription + messageDescription() + '.';
|
|
});
|
|
} else {
|
|
return fail(function() {
|
|
return 'Expected function to throw ' + errorTypeDescription + messageDescription() +
|
|
', but it threw ' + thrownDescription(thrown) + '.';
|
|
});
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
function isStringOrRegExp(potential) {
|
|
return potential instanceof RegExp || (typeof potential == 'string');
|
|
}
|
|
|
|
function isAnErrorType(type) {
|
|
if (typeof type !== 'function') {
|
|
return false;
|
|
}
|
|
|
|
var Surrogate = function() {};
|
|
Surrogate.prototype = type.prototype;
|
|
return j$.isError_(new Surrogate());
|
|
}
|
|
}
|
|
|
|
function pass(message) {
|
|
return {
|
|
pass: true,
|
|
message: message
|
|
};
|
|
}
|
|
|
|
function fail(message) {
|
|
return {
|
|
pass: false,
|
|
message: message
|
|
};
|
|
}
|
|
|
|
return toThrowError;
|
|
};
|