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') {