index.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. 'use strict';
  2. /* !
  3. * Chai - getFuncName utility
  4. * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
  5. * MIT Licensed
  6. */
  7. /**
  8. * ### .getFuncName(constructorFn)
  9. *
  10. * Returns the name of a function.
  11. * When a non-function instance is passed, returns `null`.
  12. * This also includes a polyfill function if `aFunc.name` is not defined.
  13. *
  14. * @name getFuncName
  15. * @param {Function} funct
  16. * @namespace Utils
  17. * @api public
  18. */
  19. var toString = Function.prototype.toString;
  20. var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/;
  21. var maxFunctionSourceLength = 512;
  22. function getFuncName(aFunc) {
  23. if (typeof aFunc !== 'function') {
  24. return null;
  25. }
  26. var name = '';
  27. if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') {
  28. // eslint-disable-next-line prefer-reflect
  29. var functionSource = toString.call(aFunc);
  30. // To avoid unconstrained resource consumption due to pathalogically large function names,
  31. // we limit the available return value to be less than 512 characters.
  32. if (functionSource.indexOf('(') > maxFunctionSourceLength) {
  33. return name;
  34. }
  35. // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined
  36. var match = functionSource.match(functionNameMatch);
  37. if (match) {
  38. name = match[1];
  39. }
  40. } else {
  41. // If we've got a `name` property we just use it
  42. name = aFunc.name;
  43. }
  44. return name;
  45. }
  46. module.exports = getFuncName;