blob: 603ef50b1c6a41f65419c1fb815142b8d682f750 [file] [log] [blame]
'use strict';
/* !
* Chai - checkError utility
* Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
* MIT Licensed
*/
/**
* ### .checkError
*
* Checks that an error conforms to a given set of criteria and/or retrieves information about it.
*
* @api public
*/
/**
* ### .compatibleInstance(thrown, errorLike)
*
* Checks if two instances are compatible (strict equal).
* Returns false if errorLike is not an instance of Error, because instances
* can only be compatible if they're both error instances.
*
* @name compatibleInstance
* @param {Error} thrown error
* @param {Error|ErrorConstructor} errorLike object to compare against
* @namespace Utils
* @api public
*/
function compatibleInstance(thrown, errorLike) {
return errorLike instanceof Error && thrown === errorLike;
}
/**
* ### .compatibleConstructor(thrown, errorLike)
*
* Checks if two constructors are compatible.
* This function can receive either an error constructor or
* an error instance as the `errorLike` argument.
* Constructors are compatible if they're the same or if one is
* an instance of another.
*
* @name compatibleConstructor
* @param {Error} thrown error
* @param {Error|ErrorConstructor} errorLike object to compare against
* @namespace Utils
* @api public
*/
function compatibleConstructor(thrown, errorLike) {
if (errorLike instanceof Error) {
// If `errorLike` is an instance of any error we compare their constructors
return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor;
} else if (errorLike.prototype instanceof Error || errorLike === Error) {
// If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly
return thrown.constructor === errorLike || thrown instanceof errorLike;
}
return false;
}
/**
* ### .compatibleMessage(thrown, errMatcher)
*
* Checks if an error's message is compatible with a matcher (String or RegExp).
* If the message contains the String or passes the RegExp test,
* it is considered compatible.
*
* @name compatibleMessage
* @param {Error} thrown error
* @param {String|RegExp} errMatcher to look for into the message
* @namespace Utils
* @api public
*/
function compatibleMessage(thrown, errMatcher) {
var comparisonString = typeof thrown === 'string' ? thrown : thrown.message;
if (errMatcher instanceof RegExp) {
return errMatcher.test(comparisonString);
} else if (typeof errMatcher === 'string') {
return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers
}
return false;
}
/**
* ### .getFunctionName(constructorFn)
*
* Returns the name of a function.
* This also includes a polyfill function if `constructorFn.name` is not defined.
*
* @name getFunctionName
* @param {Function} constructorFn
* @namespace Utils
* @api private
*/
var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/;
function getFunctionName(constructorFn) {
var name = '';
if (typeof constructorFn.name === 'undefined') {
// Here we run a polyfill if constructorFn.name is not defined
var match = String(constructorFn).match(functionNameMatch);
if (match) {
name = match[1];
}
} else {
name = constructorFn.name;
}
return name;
}
/**
* ### .getConstructorName(errorLike)
*
* Gets the constructor name for an Error instance or constructor itself.
*
* @name getConstructorName
* @param {Error|ErrorConstructor} errorLike
* @namespace Utils
* @api public
*/
function getConstructorName(errorLike) {
var constructorName = errorLike;
if (errorLike instanceof Error) {
constructorName = getFunctionName(errorLike.constructor);
} else if (typeof errorLike === 'function') {
// If `err` is not an instance of Error it is an error constructor itself or another function.
// If we've got a common function we get its name, otherwise we may need to create a new instance
// of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more.
constructorName = getFunctionName(errorLike).trim() ||
getFunctionName(new errorLike()); // eslint-disable-line new-cap
}
return constructorName;
}
/**
* ### .getMessage(errorLike)
*
* Gets the error message from an error.
* If `err` is a String itself, we return it.
* If the error has no message, we return an empty string.
*
* @name getMessage
* @param {Error|String} errorLike
* @namespace Utils
* @api public
*/
function getMessage(errorLike) {
var msg = '';
if (errorLike && errorLike.message) {
msg = errorLike.message;
} else if (typeof errorLike === 'string') {
msg = errorLike;
}
return msg;
}
module.exports = {
compatibleInstance: compatibleInstance,
compatibleConstructor: compatibleConstructor,
compatibleMessage: compatibleMessage,
getMessage: getMessage,
getConstructorName: getConstructorName,
};