lowcode-engine/packages/designer/tests/plugin/plugin-manager.test.ts
2021-11-03 17:55:42 +08:00

218 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import '../fixtures/window';
import { Editor } from '@ali/lowcode-editor-core';
import { LowCodePluginManager } from '../../src/plugin/plugin-manager';
import { ILowCodePluginContext, ILowCodePluginManager } from '../../src/plugin/plugin-types';
const editor = new Editor();
describe('plugin 测试', () => {
let pluginManager: ILowCodePluginManager;
beforeEach(() => {
pluginManager = new LowCodePluginManager(editor).toProxy();
});
afterEach(() => {
pluginManager.dispose();
});
it('注册插件,插件参数生成函数能被调用,且能拿到正确的 ctx / options', () => {
const mockFn = jest.fn();
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
mockFn(ctx, options);
return {
name: 'demo1',
};
}, { test: 1 });
const [expectedCtx, expectedOptions] = mockFn.mock.calls[0];
expect(expectedCtx).toHaveProperty('designer');
expect(expectedCtx).toHaveProperty('designerCabin');
expect(expectedCtx).toHaveProperty('editor');
expect(expectedCtx).toHaveProperty('hotkey');
expect(expectedCtx).toHaveProperty('plugins');
expect(expectedCtx).toHaveProperty('skeleton');
expect(expectedCtx).toHaveProperty('logger');
expect(expectedOptions).toEqual({ test: 1 });
});
it('注册插件,调用插件 init 方法', async () => {
const mockFn = jest.fn();
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
init: mockFn,
exports() {
return {
x: 1,
y: 2,
};
},
};
}, { test: 1 });
await pluginManager.init();
expect(pluginManager.size).toBe(1);
expect(pluginManager.has('demo1')).toBeTruthy();
expect(pluginManager.get('demo1')!.isInited()).toBeTruthy();
expect(pluginManager.demo1).toBeTruthy();
expect(pluginManager.demo1.x).toBe(1);
expect(pluginManager.demo1.y).toBe(2);
expect(mockFn).toHaveBeenCalled();
});
it('注册插件,调用 setDisabled 方法', async () => {
const mockFn = jest.fn();
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
init: mockFn,
};
}, { test: 1 });
await pluginManager.init();
expect(pluginManager.demo1).toBeTruthy();
pluginManager.setDisabled('demo1', true);
expect(pluginManager.demo1).toBeUndefined();
});
it('删除插件,调用插件 destory 方法', async () => {
const mockFn = jest.fn();
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
destroy: mockFn,
};
}, { test: 1 });
await pluginManager.init();
await pluginManager.delete('demo1');
expect(mockFn).toHaveBeenCalled();
await pluginManager.delete('non-existing');
});
it('dep 依赖', async () => {
const mockFn = jest.fn();
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
dep: ['demo2'],
init: () => mockFn('demo1'),
};
});
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo2',
init: () => mockFn('demo2'),
};
});
await pluginManager.init();
expect(mockFn).toHaveBeenNthCalledWith(1, 'demo2');
expect(mockFn).toHaveBeenNthCalledWith(2, 'demo1');
});
it('autoInit 功能', async () => {
const mockFn = jest.fn();
await pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
init: mockFn,
};
}, { test: 1 }, { autoInit: true });
expect(mockFn).toHaveBeenCalled();
});
it('插件不会重复 init除非强制重新 init', async () => {
const mockFn = jest.fn();
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
init: mockFn,
};
}, { test: 1 });
await pluginManager.init();
expect(mockFn).toHaveBeenCalledTimes(1);
pluginManager.get('demo1')!.init();
expect(mockFn).toHaveBeenCalledTimes(1);
pluginManager.get('demo1')!.init(true);
expect(mockFn).toHaveBeenCalledTimes(2);
});
it('默认情况不允许重复注册', async () => {
const mockFn = jest.fn();
const mockPlugin = (ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demoDuplicated',
init: mockFn,
};
};
pluginManager.register(mockPlugin, { test: 1 });
pluginManager.register(mockPlugin, { test: 1 }).catch(e => {
expect(e).toEqual(new Error('Plugin with name demoDuplicated exists'));
});
await pluginManager.init();
});
it('插件增加 override 参数时可以重复注册', async () => {
const mockFn = jest.fn();
const mockPlugin = (ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demoOverride',
init: mockFn,
};
};
pluginManager.register(mockPlugin, { test: 1 });
pluginManager.register(mockPlugin, { test: 1 }, { override: true });
await pluginManager.init();
});
it('插件增加 override 参数时可以重复注册, 被覆盖的如果已初始化,会被销毁', async () => {
const mockInitFn = jest.fn();
const mockDestroyFn = jest.fn();
const mockPlugin = (ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demoOverride',
init: mockInitFn,
destroy: mockDestroyFn,
};
};
await pluginManager.register(mockPlugin, { test: 1 }, { autoInit: true });
expect(mockInitFn).toHaveBeenCalledTimes(1);
await pluginManager.register(mockPlugin, { test: 1 }, { override: true });
expect(mockDestroyFn).toHaveBeenCalledTimes(1);
await pluginManager.init();
});
it('内部事件机制', async () => {
const mockFn = jest.fn();
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
};
}, { test: 1 });
await pluginManager.init();
const plugin = pluginManager.get('demo1')!;
plugin.on('haha', mockFn);
plugin.emit('haha', 1, 2, 3);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledWith(1, 2, 3);
plugin.removeAllListeners('haha');
plugin.emit('haha', 1, 2, 3);
expect(mockFn).toHaveBeenCalledTimes(1);
});
it('dispose 方法', async () => {
pluginManager.register((ctx: ILowCodePluginContext, options: any) => {
return {
name: 'demo1',
};
}, { test: 1 });
await pluginManager.init();
const plugin = pluginManager.get('demo1')!;
await plugin.dispose();
expect(pluginManager.has('demo1')).toBeFalsy();
});
});