diff --git a/src/__tests__/__snapshots__/main-test.js.snap b/src/__tests__/__snapshots__/main-test.js.snap index 3c28f247ea9..2e17ed8b7bc 100644 --- a/src/__tests__/__snapshots__/main-test.js.snap +++ b/src/__tests__/__snapshots__/main-test.js.snap @@ -62,6 +62,7 @@ Object { exports[`main fixtures processes component "component_4.js" without errors 1`] = ` Object { "description": "", + "displayName": "Parent", "methods": Array [], "props": Object { "child": Object { @@ -176,6 +177,7 @@ Object { exports[`main fixtures processes component "component_8.js" without errors 1`] = ` Object { "description": "", + "displayName": "Parent", "methods": Array [ Object { "docblock": null, @@ -197,6 +199,7 @@ Object { exports[`main fixtures processes component "component_9.js" without errors 1`] = ` Object { "description": "Should be recognized as component.", + "displayName": "ExampleComponent", "methods": Array [], } `; @@ -204,6 +207,7 @@ Object { exports[`main fixtures processes component "component_10.js" without errors 1`] = ` Object { "description": "React component that display current time at current location.", + "displayName": "Clock", "methods": Array [ Object { "description": "Update clock state with new time", diff --git a/src/handlers/__tests__/displayNameHandler-test.js b/src/handlers/__tests__/displayNameHandler-test.js index 743bf1b3dad..a6358d14512 100644 --- a/src/handlers/__tests__/displayNameHandler-test.js +++ b/src/handlers/__tests__/displayNameHandler-test.js @@ -70,9 +70,28 @@ describe('defaultPropsHandler', () => { expect(documentation.displayName).not.toBeDefined(); }); - describe('ClassDeclaration displayName getter', () => { + describe('ClassDeclaration', () => { - it('considers class methods', () => { + it('considers the class name', () => { + const definition = statement(` + class Foo { + } + `); + expect(() => displayNameHandler(documentation, definition)).not.toThrow(); + expect(documentation.displayName).toBe('Foo'); + }); + + it('considers a static displayName class property', () => { + const definition = statement(` + class Foo { + static displayName = 'foo'; + } + `); + expect(() => displayNameHandler(documentation, definition)).not.toThrow(); + expect(documentation.displayName).toBe('foo'); + }); + + it('considers static displayName getter', () => { const definition = statement(` class Foo { static get displayName() { @@ -84,7 +103,7 @@ describe('defaultPropsHandler', () => { expect(documentation.displayName).toBe('foo'); }); - it('resolves variables in class methods', () => { + it('resolves variables in displayName getter', () => { const definition = statement(` class Foo { static get displayName() { diff --git a/src/handlers/displayNameHandler.js b/src/handlers/displayNameHandler.js index 4878ff5b53b..aef3e54abf5 100644 --- a/src/handlers/displayNameHandler.js +++ b/src/handlers/displayNameHandler.js @@ -13,6 +13,7 @@ import type Documentation from '../Documentation'; import getMemberValuePath from '../utils/getMemberValuePath'; +import getNameOrValue from '../utils/getNameOrValue'; import recast from 'recast'; import resolveToValue from '../utils/resolveToValue'; import {traverseShallow} from '../utils/traverse'; @@ -25,6 +26,14 @@ export default function displayNameHandler( ) { let displayNamePath = getMemberValuePath(path, 'displayName'); if (!displayNamePath) { + // Function and class declarations need special treatment. The name of the + // function / class is the displayName + if ( + types.ClassDeclaration.check(path.node) || + types.FunctionDeclaration.check(path.node) + ) { + documentation.set('displayName', getNameOrValue(path.get('id'))); + } return; } displayNamePath = resolveToValue(displayNamePath);