lowcode-engine/packages/designer/tests/main/meta/component-meta.test.ts

253 lines
9.3 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 { 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']);
});
});