diff --git a/packages/react-devtools-shared/src/__tests__/utils-test.js b/packages/react-devtools-shared/src/__tests__/utils-test.js new file mode 100644 index 0000000000000..37e445974a28c --- /dev/null +++ b/packages/react-devtools-shared/src/__tests__/utils-test.js @@ -0,0 +1,40 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import {getDisplayName} from 'react-devtools-shared/src/utils'; + +describe('utils', () => { + describe('getDisplayName', () => { + it('should return a function name', () => { + function FauxComponent() {} + expect(getDisplayName(FauxComponent)).toEqual('FauxComponent'); + }); + + it('should return a displayName name if specified', () => { + function FauxComponent() {} + FauxComponent.displayName = 'OverrideDisplayName'; + expect(getDisplayName(FauxComponent)).toEqual('OverrideDisplayName'); + }); + + it('should return the fallback for anonymous functions', () => { + expect(getDisplayName(() => {}, 'Fallback')).toEqual('Fallback'); + }); + + it('should return Anonymous for anonymous functions without a fallback', () => { + expect(getDisplayName(() => {})).toEqual('Anonymous'); + }); + + // Simulate a reported bug: + // https://github.com/facebook/react/issues/16685 + it('should return a fallback when the name prop is not a string', () => { + const FauxComponent = {name: {}}; + expect(getDisplayName(FauxComponent, 'Fallback')).toEqual('Fallback'); + }); + }); +}); diff --git a/packages/react-devtools-shared/src/utils.js b/packages/react-devtools-shared/src/utils.js index 990ecf996896e..5c22b92100b62 100644 --- a/packages/react-devtools-shared/src/utils.js +++ b/packages/react-devtools-shared/src/utils.js @@ -46,17 +46,15 @@ export function getDisplayName( return nameFromCache; } - let displayName; + let displayName = fallbackName; // The displayName property is not guaranteed to be a string. // It's only safe to use for our purposes if it's a string. // github.com/facebook/react-devtools/issues/803 if (typeof type.displayName === 'string') { displayName = type.displayName; - } - - if (!displayName) { - displayName = type.name || fallbackName; + } else if (typeof type.name === 'string' && type.name !== '') { + displayName = type.name; } cachedDisplayNames.set(type, displayName);