Skip to content

Commit

Permalink
Add reactify (#51)
Browse files Browse the repository at this point in the history
feat: Add `reactify` function from `incubator-superset`
  • Loading branch information
kristw authored and zhaoyongjie committed Nov 26, 2021
1 parent a4c3e7d commit 3b54039
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"prettier": "beemo prettier \"./packages/*/{src,test,storybook}/**/*.{js,jsx,ts,tsx,json,md}\"",
"release": "yarn run prepare-release && lerna publish && yarn run postrelease",
"test": "yarn run jest",
"test:watch": "beemo create-config jest && jest --watch"
"test:watch": "beemo create-config jest --react && jest --watch"
},
"repository": "https://github.com/apache-superset/superset-ui.git",
"keywords": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';

export default function reactify(renderFn) {
class ReactifiedComponent extends React.Component {
constructor(props) {
super(props);
this.setContainerRef = this.setContainerRef.bind(this);
}

componentDidMount() {
this.execute();
}

componentDidUpdate() {
this.execute();
}

componentWillUnmount() {
this.container = null;
}

setContainerRef(c) {
this.container = c;
}

execute() {
if (this.container) {
renderFn(this.container, this.props);
}
}

render() {
const { id, className } = this.props;

return <div id={id} className={className} ref={this.setContainerRef} />;
}
}

if (renderFn.displayName) {
ReactifiedComponent.displayName = renderFn.displayName;
}
/* eslint-disable-next-line react/forbid-foreign-prop-types */
if (renderFn.propTypes) {
ReactifiedComponent.propTypes = renderFn.propTypes;
}
if (renderFn.defaultProps) {
ReactifiedComponent.defaultProps = renderFn.defaultProps;
}

return ReactifiedComponent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { default as ChartPlugin } from './models/ChartPlugin';
export { default as ChartProps } from './models/ChartProps';

export { default as createLoadableRenderer } from './components/createLoadableRenderer';
export { default as reactify } from './components/reactify';

export {
default as getChartBuildQueryRegistry,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { shallow } from 'enzyme';
import createLoadableRenderer from '../../src/components/createLoadableRenderer';
import { createLoadableRenderer } from '../../src';

describe('createLoadableRenderer', () => {
function TestComponent() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import PropTypes from 'prop-types';
import React from 'react';
import { mount } from 'enzyme';
import { reactify } from '../../src';

describe('reactify(renderFn)', () => {
const renderFn = jest.fn((element, props) => {
const container = element;
container.innerHTML = '';
const child = document.createElement('b');
child.innerHTML = props.content;
container.appendChild(child);
});

renderFn.displayName = 'BoldText';
renderFn.propTypes = {
content: PropTypes.string,
};
renderFn.defaultProps = {
content: 'ghi',
};

const TheChart = reactify(renderFn);

class TestComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = { content: 'abc' };
}

componentDidMount() {
setTimeout(() => {
this.setState({ content: 'def' });
}, 10);
}

render() {
const { content } = this.state;

return <TheChart content={content} />;
}
}

it('returns a React component class', done => {
const wrapper = mount(<TestComponent />);
expect(renderFn).toHaveBeenCalledTimes(1);
expect(wrapper.html()).toEqual('<div><b>abc</b></div>');
setTimeout(() => {
expect(renderFn).toHaveBeenCalledTimes(2);
expect(wrapper.html()).toEqual('<div><b>def</b></div>');
wrapper.unmount();
done();
}, 20);
});
describe('displayName', () => {
it('has displayName if renderFn.displayName is defined', () => {
expect(TheChart.displayName).toEqual('BoldText');
});
it('does not have displayName if renderFn.displayName is not defined', () => {
const AnotherChart = reactify(() => {});
expect(AnotherChart.displayName).toBeUndefined();
});
});
describe('propTypes', () => {
it('has propTypes if renderFn.propTypes is defined', () => {
/* eslint-disable-next-line react/forbid-foreign-prop-types */
expect(TheChart.propTypes).toBe(renderFn.propTypes);
});
it('does not have propTypes if renderFn.propTypes is not defined', () => {
const AnotherChart = reactify(() => {});
/* eslint-disable-next-line react/forbid-foreign-prop-types */
expect(AnotherChart.propTypes).toBeUndefined();
});
});
describe('defaultProps', () => {
it('has defaultProps if renderFn.defaultProps is defined', () => {
expect(TheChart.defaultProps).toBe(renderFn.defaultProps);
const wrapper = mount(<TheChart />);
expect(wrapper.html()).toEqual('<div><b>ghi</b></div>');
});
it('does not have defaultProps if renderFn.defaultProps is not defined', () => {
const AnotherChart = reactify(() => {});
expect(AnotherChart.defaultProps).toBeUndefined();
});
});
it('does not try to render if not mounted', () => {
const anotherRenderFn = jest.fn();
const AnotherChart = reactify(anotherRenderFn);
new AnotherChart().execute();
expect(anotherRenderFn).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getChartComponentRegistry,
getChartMetadataRegistry,
getChartTransformPropsRegistry,
reactify,
} from '../src/index';

describe('index', () => {
Expand All @@ -20,6 +21,7 @@ describe('index', () => {
getChartComponentRegistry,
getChartMetadataRegistry,
getChartTransformPropsRegistry,
reactify,
].forEach(x => expect(x).toBeDefined());
});
});

0 comments on commit 3b54039

Please sign in to comment.