; | |
/* ! | |
* Chai - getFuncName utility | |
* Copyright(c) 2012-2016 Jake Luer <[email protected]> | |
* MIT Licensed | |
*/ | |
/** | |
* ### .getFuncName(constructorFn) | |
* | |
* Returns the name of a function. | |
* When a non-function instance is passed, returns `null`. | |
* This also includes a polyfill function if `aFunc.name` is not defined. | |
* | |
* @name getFuncName | |
* @param {Function} funct | |
* @namespace Utils | |
* @api public | |
*/ | |
var toString = Function.prototype.toString; | |
var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; | |
var maxFunctionSourceLength = 512; | |
function getFuncName(aFunc) { | |
if (typeof aFunc !== 'function') { | |
return null; | |
} | |
var name = ''; | |
if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { | |
// eslint-disable-next-line prefer-reflect | |
var functionSource = toString.call(aFunc); | |
// To avoid unconstrained resource consumption due to pathalogically large function names, | |
// we limit the available return value to be less than 512 characters. | |
if (functionSource.indexOf('(') > maxFunctionSourceLength) { | |
return name; | |
} | |
// Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined | |
var match = functionSource.match(functionNameMatch); | |
if (match) { | |
name = match[1]; | |
} | |
} else { | |
// If we've got a `name` property we just use it | |
name = aFunc.name; | |
} | |
return name; | |
} | |
module.exports = getFuncName; | |