Skip to content

Commit

Permalink
Add createLoadableRenderer (#49)
Browse files Browse the repository at this point in the history
feat: Add `createLoadableRenderer`
  • Loading branch information
kristw authored and zhaoyongjie committed Nov 26, 2021
1 parent 0f3bd0c commit a4c3e7d
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"build:esm": "NODE_ENV=production beemo babel ./src --out-dir esm/ --esm --minify --workspaces=\"@superset-ui/!(demo|generator-superset)\"",
"build:ts": "NODE_ENV=production beemo typescript --workspaces=\"@superset-ui/(connection|chart)\"",
"lint": "beemo create-config prettier && beemo eslint \"./packages/*/{src,test,storybook}/**/*.{js,jsx,ts,tsx}\"",
"jest": "beemo jest --color --coverage",
"jest": "beemo jest --color --coverage --react",
"postrelease": "lerna run gh-pages",
"prepare-release": "git checkout master && git pull --rebase origin master && lerna bootstrap && yarn run test",
"prerelease": "yarn run build",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@
"access": "public"
},
"dependencies": {
"@superset-ui/core": "^0.3.0",
"@superset-ui/core": "^0.7.0",
"prop-types": "^15.6.2",
"react-loadable": "^5.5.0",
"reselect": "^4.0.0"
},
"devDependencies": {
"react": "^15 || ^16"
},
"peerDependencies": {
"react": "^15 || ^16"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Loadable from 'react-loadable';
import PropTypes from 'prop-types';

const propTypes = {
onRenderFailure: PropTypes.func,
onRenderSuccess: PropTypes.func,
};

const defaultProps = {
onRenderFailure() {},
onRenderSuccess() {},
};

export default function createLoadableRenderer(options) {
/* eslint-disable-next-line babel/new-cap */
const LoadableRenderer = Loadable.Map(options);

// Extends the behavior of LoadableComponent
// generated by react-loadable
// to provide post-render listeners
class CustomLoadableRenderer extends LoadableRenderer {
componentDidMount() {
this.afterRender();
}

componentDidUpdate() {
this.afterRender();
}

afterRender() {
const { loaded, loading, error } = this.state;
if (!loading) {
if (error) {
this.props.onRenderFailure(error);
} else if (loaded && Object.keys(loaded).length > 0) {
this.props.onRenderSuccess();
}
}
}
}

CustomLoadableRenderer.defaultProps = defaultProps;
CustomLoadableRenderer.propTypes = propTypes;
CustomLoadableRenderer.preload = LoadableRenderer.preload;

return CustomLoadableRenderer;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export { default as ChartMetadata } from './models/ChartMetadata';
export { default as ChartPlugin } from './models/ChartPlugin';
export { default as ChartProps } from './models/ChartProps';

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

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

describe('createLoadableRenderer', () => {
function TestComponent() {
return <div className="test-component">test</div>;
}
let loadChartSuccess;
let render;
let loading;
let LoadableRenderer;

beforeEach(() => {
loadChartSuccess = jest.fn(() => Promise.resolve(TestComponent));
render = jest.fn(loaded => {
const { Chart } = loaded;

return <Chart />;
});
loading = jest.fn(() => <div>Loading</div>);
LoadableRenderer = createLoadableRenderer({
loader: {
Chart: loadChartSuccess,
},
loading,
render,
});
});

describe('returns a LoadableRenderer class', () => {
it('LoadableRenderer.preload() preloads the lazy-load components', () => {
expect(LoadableRenderer.preload).toBeInstanceOf(Function);
LoadableRenderer.preload();
expect(loadChartSuccess).toHaveBeenCalledTimes(1);
});

it('calls onRenderSuccess when succeeds', done => {
const onRenderSuccess = jest.fn();
const onRenderFailure = jest.fn();
shallow(
<LoadableRenderer onRenderSuccess={onRenderSuccess} onRenderFailure={onRenderFailure} />,
);
expect(loadChartSuccess).toHaveBeenCalled();
setTimeout(() => {
expect(render).toHaveBeenCalledTimes(1);
expect(onRenderSuccess).toHaveBeenCalledTimes(1);
expect(onRenderFailure).not.toHaveBeenCalled();
done();
}, 10);
});

it('calls onRenderFailure when fails', done => {
const loadChartFailure = jest.fn(() => Promise.reject(new Error('Invalid chart')));
const FailedRenderer = createLoadableRenderer({
loader: {
Chart: loadChartFailure,
},
loading,
render,
});
const onRenderSuccess = jest.fn();
const onRenderFailure = jest.fn();
shallow(
<FailedRenderer onRenderSuccess={onRenderSuccess} onRenderFailure={onRenderFailure} />,
);
expect(loadChartFailure).toHaveBeenCalledTimes(1);
setTimeout(() => {
expect(render).not.toHaveBeenCalled();
expect(onRenderSuccess).not.toHaveBeenCalled();
expect(onRenderFailure).toHaveBeenCalledTimes(1);
done();
}, 10);
});

it('renders the lazy-load components', done => {
const wrapper = shallow(<LoadableRenderer />);
// lazy-loaded component not rendered immediately
expect(wrapper.find(TestComponent)).toHaveLength(0);
setTimeout(() => {
// but rendered after the component is loaded.
expect(wrapper.find(TestComponent)).toHaveLength(1);
done();
}, 10);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
ChartMetadata,
ChartPlugin,
ChartProps,
createLoadableRenderer,
getChartBuildQueryRegistry,
getChartComponentRegistry,
getChartMetadataRegistry,
Expand All @@ -14,6 +15,7 @@ describe('index', () => {
ChartMetadata,
ChartPlugin,
ChartProps,
createLoadableRenderer,
getChartBuildQueryRegistry,
getChartComponentRegistry,
getChartMetadataRegistry,
Expand Down

0 comments on commit a4c3e7d

Please sign in to comment.