feat: allow chart plugin to be unregistered (#168)

* feat: allow chart plugin to be unregistered

* test: address edge cases
This commit is contained in:
Krist Wongsuphasawat 2019-06-11 18:08:12 -07:00 committed by Yongjie Zhao
parent 62204a9dde
commit 09f9405334
4 changed files with 91 additions and 13 deletions

View File

@ -17,17 +17,17 @@ type ValueOrModuleWithValue<T> = T | { default: T };
interface ChartPluginConfig<T extends ChartFormData> { interface ChartPluginConfig<T extends ChartFormData> {
metadata: ChartMetadata; metadata: ChartMetadata;
// use buildQuery for immediate value /** Use buildQuery for immediate value. For lazy-loading, use loadBuildQuery. */
buildQuery?: BuildQueryFunction<T>; buildQuery?: BuildQueryFunction<T>;
// use loadBuildQuery for dynamic import (lazy-loading) /** Use loadBuildQuery for dynamic import (lazy-loading) */
loadBuildQuery?: PromiseOrValueLoader<ValueOrModuleWithValue<BuildQueryFunction<T>>>; loadBuildQuery?: PromiseOrValueLoader<ValueOrModuleWithValue<BuildQueryFunction<T>>>;
// use transformProps for immediate value /** Use transformProps for immediate value. For lazy-loading, use loadTransformProps. */
transformProps?: TransformProps; transformProps?: TransformProps;
// use loadTransformProps for dynamic import (lazy-loading) /** Use loadTransformProps for dynamic import (lazy-loading) */
loadTransformProps?: PromiseOrValueLoader<ValueOrModuleWithValue<TransformProps>>; loadTransformProps?: PromiseOrValueLoader<ValueOrModuleWithValue<TransformProps>>;
// use Chart for immediate value /** Use Chart for immediate value. For lazy-loading, use loadChart. */
Chart?: ChartType; Chart?: ChartType;
// use loadChart for dynamic import (lazy-loading) /** Use loadChart for dynamic import (lazy-loading) */
loadChart?: PromiseOrValueLoader<ValueOrModuleWithValue<ChartType>>; loadChart?: PromiseOrValueLoader<ValueOrModuleWithValue<ChartType>>;
} }
@ -92,6 +92,16 @@ export default class ChartPlugin<T extends ChartFormData = ChartFormData> extend
return this; return this;
} }
unregister() {
const { key = isRequired('config.key') } = this.config;
getChartMetadataRegistry().remove(key);
getChartComponentRegistry().remove(key);
getChartTransformPropsRegistry().remove(key);
getChartBuildQueryRegistry().remove(key);
return this;
}
configure(config: { [key: string]: any }, replace?: boolean) { configure(config: { [key: string]: any }, replace?: boolean) {
super.configure(config, replace); super.configure(config, replace);

View File

@ -8,6 +8,10 @@ import {
ChartProps, ChartProps,
BuildQueryFunction, BuildQueryFunction,
TransformProps, TransformProps,
getChartMetadataRegistry,
getChartComponentRegistry,
getChartTransformPropsRegistry,
getChartBuildQueryRegistry,
} from '../../src'; } from '../../src';
describe('ChartPlugin', () => { describe('ChartPlugin', () => {
@ -18,7 +22,7 @@ describe('ChartPlugin', () => {
thumbnail: '', thumbnail: '',
}); });
const buildQuery = (_: ChartFormData) => ({ const buildQuery = () => ({
datasource: { id: 1, type: DatasourceType.Table }, datasource: { id: 1, type: DatasourceType.Table },
queries: [{ granularity: 'day' }], queries: [{ granularity: 'day' }],
}); });
@ -132,17 +136,70 @@ describe('ChartPlugin', () => {
}); });
describe('.register()', () => { describe('.register()', () => {
const plugin = new ChartPlugin({ let plugin: ChartPlugin;
beforeEach(() => {
plugin = new ChartPlugin({
metadata, metadata,
Chart: FakeChart, Chart: FakeChart,
buildQuery, buildQuery,
}); });
});
it('throws an error if key is not provided', () => { it('throws an error if key is not provided', () => {
expect(() => plugin.register()).toThrowError(Error); expect(() => plugin.register()).toThrowError(Error);
expect(() => plugin.configure({ key: 'abc' }).register()).not.toThrowError(Error); expect(() => plugin.configure({ key: 'ab' }).register()).not.toThrowError(Error);
});
it('add the plugin to the registries', () => {
plugin.configure({ key: 'cd' }).register();
expect(getChartMetadataRegistry().get('cd')).toBe(metadata);
expect(getChartComponentRegistry().get('cd')).toBe(FakeChart);
expect(getChartTransformPropsRegistry().has('cd')).toEqual(true);
expect(getChartBuildQueryRegistry().get('cd')).toBe(buildQuery);
});
it('does not register buildQuery when it is not specified in the ChartPlugin', () => {
new ChartPlugin({
metadata,
Chart: FakeChart,
})
.configure({ key: 'ef' })
.register();
expect(getChartBuildQueryRegistry().has('ef')).toEqual(false);
}); });
it('returns itself', () => { it('returns itself', () => {
expect(plugin.configure({ key: 'abc' }).register()).toBe(plugin); expect(plugin.configure({ key: 'gh' }).register()).toBe(plugin);
});
});
describe('.unregister()', () => {
let plugin: ChartPlugin;
beforeEach(() => {
plugin = new ChartPlugin({
metadata,
Chart: FakeChart,
buildQuery,
});
});
it('throws an error if key is not provided', () => {
expect(() => plugin.unregister()).toThrowError(Error);
expect(() => plugin.configure({ key: 'abc' }).unregister()).not.toThrowError(Error);
});
it('removes the chart from the registries', () => {
plugin.configure({ key: 'def' }).register();
expect(getChartMetadataRegistry().get('def')).toBe(metadata);
expect(getChartComponentRegistry().get('def')).toBe(FakeChart);
expect(getChartTransformPropsRegistry().has('def')).toEqual(true);
expect(getChartBuildQueryRegistry().get('def')).toBe(buildQuery);
plugin.unregister();
expect(getChartMetadataRegistry().has('def')).toEqual(false);
expect(getChartComponentRegistry().has('def')).toEqual(false);
expect(getChartTransformPropsRegistry().has('def')).toEqual(false);
expect(getChartBuildQueryRegistry().has('def')).toEqual(false);
});
it('returns itself', () => {
expect(plugin.configure({ key: 'xyz' }).unregister()).toBe(plugin);
}); });
}); });
}); });

View File

@ -26,4 +26,8 @@ export default class Plugin {
register() { register() {
return this; return this;
} }
unregister() {
return this;
}
} }

View File

@ -50,4 +50,11 @@ describe('Plugin', () => {
expect(plugin.register()).toBe(plugin); expect(plugin.register()).toBe(plugin);
}); });
}); });
describe('.unregister()', () => {
it('returns the plugin itself', () => {
const plugin = new Plugin();
expect(plugin.unregister()).toBe(plugin);
});
});
}); });