diff --git a/package.json b/package.json index 064f823be..9658f5ea2 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "license": "MIT", "dependencies": { "cheerio": "^0.22.0", + "function.prototype.name": "^1.0.0", "is-subset": "^0.1.1", "lodash": "^4.16.4", "object-is": "^1.0.1", diff --git a/src/Debug.js b/src/Debug.js index 42bca65fa..b338d8c68 100644 --- a/src/Debug.js +++ b/src/Debug.js @@ -2,6 +2,7 @@ import without from 'lodash/without'; import escape from 'lodash/escape'; import compact from 'lodash/compact'; import objectValues from 'object.values'; +import functionName from 'function.prototype.name'; import { childrenOfNode, @@ -22,7 +23,7 @@ import { REACT013 } from './version'; export function typeName(node) { return typeof node.type === 'function' - ? (node.type.displayName || node.type.name || 'Component') + ? (node.type.displayName || functionName(node.type) || 'Component') : node.type; } diff --git a/src/ShallowTraversal.js b/src/ShallowTraversal.js index 3330a89dd..2e754f762 100644 --- a/src/ShallowTraversal.js +++ b/src/ShallowTraversal.js @@ -1,6 +1,7 @@ import React from 'react'; import isEmpty from 'lodash/isEmpty'; import isSubset from 'is-subset'; +import functionName from 'function.prototype.name'; import { propsOfNode, splitSelector, @@ -143,7 +144,7 @@ export function getTextFromNode(node) { } if (node.type && typeof node.type === 'function') { - return `<${node.type.displayName || node.type.name} />`; + return `<${node.type.displayName || functionName(node.type)} />`; } return childrenOfNode(node).map(getTextFromNode) diff --git a/src/Utils.js b/src/Utils.js index b7f90d1ef..200e34434 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -2,6 +2,7 @@ import isEqual from 'lodash/isEqual'; import React from 'react'; import is from 'object-is'; +import functionName from 'function.prototype.name'; import { isDOMComponent, findDOMNode, @@ -24,7 +25,8 @@ export function internalInstance(inst) { } export function isFunctionalComponent(inst) { - return !!inst && !!inst.constructor && inst.constructor.name === 'StatelessComponent'; + return !!inst && !!inst.constructor && typeof inst.constructor === 'function' && + functionName(inst.constructor) === 'StatelessComponent'; } export function isCustomComponentElement(inst) { @@ -62,7 +64,8 @@ export function nodeHasType(node, type) { if (!type || !node) return false; if (!node.type) return false; if (typeof node.type === 'string') return node.type === type; - return node.type.name === type || node.type.displayName === type; + return (typeof node.type === 'function' ? + functionName(node.type) === type : node.type.name === type) || node.type.displayName === type; } export function childrenEqual(a, b, lenComp) { @@ -344,5 +347,5 @@ export function displayNameOfNode(node) { if (!type) return null; - return type.displayName || type.name || type; + return type.displayName || (typeof type === 'function' ? functionName(type) : type.name) || type; }