mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-20 17:42:57 +00:00
253 lines
9.3 KiB
TypeScript
253 lines
9.3 KiB
TypeScript
import '../../fixtures/window';
|
||
import { Designer } from '../../../src/designer/designer';
|
||
import divMeta from '../../fixtures/component-metadata/div';
|
||
import div2Meta from '../../fixtures/component-metadata/div2';
|
||
import div3Meta from '../../fixtures/component-metadata/div3';
|
||
import div4Meta from '../../fixtures/component-metadata/div4';
|
||
import div5Meta from '../../fixtures/component-metadata/div5';
|
||
import div6Meta from '../../fixtures/component-metadata/div6';
|
||
import div7Meta from '../../fixtures/component-metadata/div7';
|
||
import div8Meta from '../../fixtures/component-metadata/div8';
|
||
import div9Meta from '../../fixtures/component-metadata/div9';
|
||
import div10Meta from '../../fixtures/component-metadata/div10';
|
||
import abcgroup from '../../fixtures/component-metadata/abcgroup';
|
||
import abcitem from '../../fixtures/component-metadata/abcitem';
|
||
import abcnode from '../../fixtures/component-metadata/abcnode';
|
||
import abcoption from '../../fixtures/component-metadata/abcoption';
|
||
import page2Meta from '../../fixtures/component-metadata/page2';
|
||
import {
|
||
ComponentMeta,
|
||
isComponentMeta,
|
||
ensureAList,
|
||
buildFilter,
|
||
} from '../../../src/component-meta';
|
||
|
||
|
||
jest.mock('../../../src/designer/designer', () => {
|
||
return {
|
||
Designer: jest.fn().mockImplementation(() => {
|
||
const { ComponentActions } = require('../../../src/component-actions');
|
||
return {
|
||
getGlobalComponentActions: () => [],
|
||
componentActions: new ComponentActions(),
|
||
};
|
||
}),
|
||
};
|
||
});
|
||
|
||
let designer = null;
|
||
beforeAll(() => {
|
||
designer = new Designer({} as any);
|
||
});
|
||
|
||
describe('组件元数据处理', () => {
|
||
it('构造函数', () => {
|
||
const meta = new ComponentMeta(designer, divMeta);
|
||
expect(meta.isContainer).toBeTruthy();
|
||
expect(isComponentMeta(meta)).toBeTruthy();
|
||
expect(meta.acceptable).toBeFalsy();
|
||
expect(meta.isRootComponent()).toBeFalsy();
|
||
expect(meta.isModal).toBeFalsy();
|
||
expect(meta.rootSelector).toBeUndefined();
|
||
expect(meta.liveTextEditing).toBeUndefined();
|
||
expect(meta.descriptor).toBeUndefined();
|
||
expect(typeof meta.icon).toBe('function');
|
||
expect(meta.getMetadata().title).toBe('容器');
|
||
expect(meta.title).toEqual({ type: 'i18n', 'en-US': 'Div', 'zh-CN': '容器' });
|
||
expect(meta.isMinimalRenderUnit).toBeFalsy();
|
||
expect(meta.isTopFixed).toBeFalsy();
|
||
|
||
meta.setNpm({ package: '@ali/vc-div', componentName: 'Div' });
|
||
expect(meta.npm).toEqual({ package: '@ali/vc-div', componentName: 'Div' });
|
||
meta.npm = { package: '@ali/vc-div', componentName: 'Div' };
|
||
expect(meta.npm).toEqual({ package: '@ali/vc-div', componentName: 'Div' });
|
||
|
||
|
||
const mockFn = jest.fn();
|
||
const offFn = meta.onMetadataChange(mockFn);
|
||
meta.setMetadata(divMeta);
|
||
expect(mockFn).toHaveBeenCalledTimes(1);
|
||
offFn();
|
||
meta.setMetadata(divMeta);
|
||
// 不会再触发函数
|
||
expect(mockFn).toHaveBeenCalledTimes(1);
|
||
});
|
||
|
||
it('构造函数 - 兼容场景(title 是个普通对象)', () => {
|
||
const meta = new ComponentMeta(designer, div2Meta);
|
||
expect(meta.title).toEqual('容器');
|
||
|
||
expect(meta.isTopFixed).toBeTruthy();
|
||
});
|
||
|
||
it('构造函数 - 兼容场景(title fallback 到 componentName)', () => {
|
||
const meta = new ComponentMeta(designer, div3Meta);
|
||
expect(meta.title).toEqual('Div');
|
||
});
|
||
|
||
it('构造函数 - 兼容场景(configure 是个数组)', () => {
|
||
const meta = new ComponentMeta(designer, div4Meta);
|
||
expect(meta.configure).toEqual(div4Meta.configure);
|
||
});
|
||
|
||
it('构造函数 - 兼容场景(使用 experimental)', () => {
|
||
const meta = new ComponentMeta(designer, div6Meta);
|
||
expect(meta.getMetadata().configure.advanced.initials).toHaveLength(9);
|
||
});
|
||
|
||
it('构造函数 - 兼容场景(没有 configure.component)', () => {
|
||
const meta = new ComponentMeta(designer, div7Meta);
|
||
expect(meta.isContainer).toBeFalsy();
|
||
expect(meta.isModal).toBeFalsy();
|
||
});
|
||
|
||
it('构造函数 - 兼容场景(没有 configure)', () => {
|
||
const meta = new ComponentMeta(designer, div8Meta);
|
||
expect(meta.configure).toEqual([]);
|
||
});
|
||
|
||
it('构造函数 - 兼容场景(没有 npm)', () => {
|
||
const meta = new ComponentMeta(designer, div9Meta);
|
||
expect(meta.npm).toBeUndefined();
|
||
|
||
meta.setNpm({ package: '@ali/vc-div', componentName: 'Div' });
|
||
expect(meta.npm).toEqual({ package: '@ali/vc-div', componentName: 'Div' });
|
||
});
|
||
|
||
it('availableActions', () => {
|
||
const meta = new ComponentMeta(designer, divMeta);
|
||
expect(meta.availableActions).toHaveLength(5);
|
||
expect(meta.availableActions[0].name).toBe('remove');
|
||
expect(meta.availableActions[1].name).toBe('hide');
|
||
expect(meta.availableActions[2].name).toBe('copy');
|
||
|
||
designer.componentActions.removeBuiltinComponentAction('remove');
|
||
expect(meta.availableActions).toHaveLength(4);
|
||
expect(meta.availableActions[0].name).toBe('hide');
|
||
expect(meta.availableActions[1].name).toBe('copy');
|
||
|
||
designer.componentActions.addBuiltinComponentAction({
|
||
name: 'new',
|
||
content: {
|
||
action() {},
|
||
},
|
||
});
|
||
expect(meta.availableActions).toHaveLength(5);
|
||
expect(meta.availableActions[0].name).toBe('hide');
|
||
expect(meta.availableActions[1].name).toBe('copy');
|
||
expect(meta.availableActions[4].name).toBe('new');
|
||
});
|
||
|
||
it('availableActions - disableBehaviors: *', () => {
|
||
const meta = new ComponentMeta(designer, div5Meta);
|
||
expect(meta.availableActions).toHaveLength(0);
|
||
});
|
||
|
||
it('availableActions - rootCompoment', () => {
|
||
const meta = new ComponentMeta(designer, page2Meta);
|
||
// (hide + new) left
|
||
expect(meta.availableActions).toHaveLength(2);
|
||
});
|
||
|
||
describe('checkNesting', () => {
|
||
const mockNode = (componentName) => {
|
||
return {
|
||
internalToShellNode() {
|
||
return {
|
||
componentName,
|
||
};
|
||
},
|
||
isNode: true,
|
||
};
|
||
};
|
||
const mockNodeForm = mockNode('Form');
|
||
const mockNodeImage = mockNode('Image');
|
||
const mockNodeDiv = mockNode('Div');
|
||
it('checkNestingUp', () => {
|
||
const meta1 = new ComponentMeta(designer, divMeta);
|
||
// 没有配置 parentWhitelist,判断默认为 true
|
||
expect(meta1.checkNestingUp(mockNodeDiv, mockNodeDiv)).toBeTruthy();
|
||
|
||
const meta2 = new ComponentMeta(designer, div10Meta);
|
||
expect(meta2.checkNestingUp(mockNodeDiv, mockNodeForm)).toBeTruthy();
|
||
expect(meta2.checkNestingUp(mockNodeDiv, mockNodeDiv)).toBeFalsy();
|
||
});
|
||
|
||
it('checkNestingDown', () => {
|
||
const meta1 = new ComponentMeta(designer, divMeta);
|
||
// 没有配置 childWhitelist,判断默认为 true
|
||
expect(meta1.checkNestingDown(mockNodeDiv, mockNodeDiv)).toBeTruthy();
|
||
|
||
const meta2 = new ComponentMeta(designer, div10Meta);
|
||
expect(meta2.checkNestingDown(mockNodeDiv, mockNodeForm)).toBeFalsy();
|
||
expect(meta2.checkNestingDown(mockNodeDiv, mockNodeImage)).toBeTruthy();
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('组件元数据 transducers', () => {
|
||
it('legacyIssues', () => {
|
||
const legacyMeta: any = {
|
||
...divMeta,
|
||
devMode: 'procode',
|
||
};
|
||
const meta = new ComponentMeta(designer, legacyMeta);
|
||
const metadata = meta.getMetadata();
|
||
expect(metadata.devMode).toBe('proCode');
|
||
});
|
||
});
|
||
|
||
describe('帮助函数', () => {
|
||
it('ensureAList', () => {
|
||
expect(ensureAList()).toBeNull();
|
||
expect(ensureAList(1)).toBeNull();
|
||
expect(ensureAList([])).toBeNull();
|
||
expect(ensureAList('copy lock')).toEqual(['copy', 'lock']);
|
||
expect(ensureAList(['copy', 'lock'])).toEqual(['copy', 'lock']);
|
||
});
|
||
|
||
it('buildFilter', () => {
|
||
const mockFn = () => {};
|
||
expect(buildFilter()).toBeNull();
|
||
expect(buildFilter([])).toBeNull();
|
||
expect(buildFilter(mockFn)).toBe(mockFn);
|
||
|
||
const mockRE = /xxx/;
|
||
const filter = buildFilter(mockRE);
|
||
expect(filter({ componentName: 'xxx' })).toBeTruthy();
|
||
expect(filter({ componentName: 'yyy' })).toBeFalsy();
|
||
|
||
expect(buildFilter('xxx yyy')({ componentName: 'xxx' })).toBeTruthy();
|
||
expect(buildFilter('xxx yyy')({ componentName: 'zzz' })).toBeFalsy();
|
||
});
|
||
|
||
it('registerMetadataTransducer', () => {
|
||
expect(designer.componentActions.getRegisteredMetadataTransducers()).toHaveLength(2);
|
||
// 插入到 legacy-issues 和 component-defaults 的中间
|
||
designer.componentActions.registerMetadataTransducer((metadata) => metadata, 3, 'noop');
|
||
expect(designer.componentActions.getRegisteredMetadataTransducers()).toHaveLength(3);
|
||
|
||
designer.componentActions.registerMetadataTransducer((metadata) => metadata);
|
||
expect(designer.componentActions.getRegisteredMetadataTransducers()).toHaveLength(4);
|
||
});
|
||
|
||
it('modifyBuiltinComponentAction', () => {
|
||
designer.componentActions.modifyBuiltinComponentAction('copy', (action) => {
|
||
expect(action.name).toBe('copy');
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('transducers', () => {
|
||
it('componentDefaults', () => {
|
||
const meta1 = new ComponentMeta(designer, abcgroup);
|
||
const meta2 = new ComponentMeta(designer, abcitem);
|
||
const meta3 = new ComponentMeta(designer, abcnode);
|
||
const meta4 = new ComponentMeta(designer, abcoption);
|
||
expect(meta1.getMetadata().configure.component.nestingRule.childWhitelist).toEqual(['Abc']);
|
||
expect(meta2.getMetadata().configure.component.nestingRule.parentWhitelist).toEqual(['Abc']);
|
||
expect(meta3.getMetadata().configure.component.nestingRule.parentWhitelist).toEqual(['Abc', 'Abc.Node']);
|
||
expect(meta4.getMetadata().configure.component.nestingRule.parentWhitelist).toEqual(['Abc']);
|
||
});
|
||
});
|