diff --git a/CHANGELOG.md b/CHANGELOG.md index dc260b93d..689e25158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## 0.8.1 (tbd) * Improved default template +* Fixed misidentified React class components (#82) +* Added `piral-axios` library ## 0.8.0 (October 21, 2019) diff --git a/src/packages/piral-core/src/utils/components.test.tsx b/src/packages/piral-core/src/utils/components.test.tsx new file mode 100644 index 000000000..bd8c55a61 --- /dev/null +++ b/src/packages/piral-core/src/utils/components.test.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import { convertComponent } from './components'; +import { ComponentConverters, HtmlComponent } from '../types'; + +describe('Component Converters Module', () => { + it('React FC is correctly marked', () => { + const Component = () =>
; + const converters: ComponentConverters = { + html() { + return undefined; + }, + }; + const result = convertComponent(converters, Component, 'test'); + expect(result).toHaveProperty('displayName', 'test'); + expect(result).not.toHaveProperty('converted'); + }); + + it('React class component is correctly marked', () => { + const Component = class extends React.Component { + render() { + return
; + } + }; + const converters: ComponentConverters = { + html() { + return undefined; + }, + }; + const result = convertComponent(converters, Component, 'test'); + expect(result).toHaveProperty('displayName', 'test'); + expect(result).not.toHaveProperty('converted'); + }); + + it('React exotic component is correctly marked', () => { + const Component = React.lazy(() => + Promise.resolve().then(() => ({ + default: () =>
, + })), + ); + const converters: ComponentConverters = { + html() { + return undefined; + }, + }; + const result = convertComponent(converters, Component, 'test'); + expect(result).toHaveProperty('displayName', 'test'); + expect(result).not.toHaveProperty('converted'); + }); + + it('HTML component is correctly marked', () => { + const Component: HtmlComponent = { + type: 'html', + render() { + return undefined; + }, + }; + const converters: ComponentConverters = { + html(): any { + return { + converted: true, + }; + }, + }; + const result = convertComponent(converters, Component, 'test'); + expect(result).not.toHaveProperty('displayName'); + expect(result).toHaveProperty('converted', true); + }); + + it('Unknown component throws', () => { + const Component = { + type: 'foo', + }; + const converters: ComponentConverters = { + html() { + return undefined; + }, + }; + expect(() => convertComponent(converters, Component as any, 'test')).toThrow(); + }); +}); diff --git a/src/packages/piral-core/src/utils/components.ts b/src/packages/piral-core/src/utils/components.ts index 3e6ff567c..62614b0f9 100644 --- a/src/packages/piral-core/src/utils/components.ts +++ b/src/packages/piral-core/src/utils/components.ts @@ -1,6 +1,10 @@ -import { ComponentType } from 'react'; +import { ComponentType, ExoticComponent } from 'react'; import { AnyComponent, ComponentConverters } from '../types'; +function isNotExotic(component: any): component is object { + return !(component as ExoticComponent).$$typeof; +} + export function markReact(arg: ComponentType, displayName: string) { if (arg && !arg.displayName) { arg.displayName = displayName; @@ -12,7 +16,7 @@ export function convertComponent( component: AnyComponent, displayName: string, ) { - if (typeof component === 'object') { + if (typeof component === 'object' && isNotExotic(component)) { const converter = converters[component.type]; if (typeof converter !== 'function') {