mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-10 01:48:18 +00:00
feat: 暴露 registerMetadataTransducer 接口
chore(test): 补充单测
This commit is contained in:
parent
314783d7c6
commit
cd12677138
@ -14,6 +14,7 @@ module.exports = {
|
|||||||
collectCoverage: false,
|
collectCoverage: false,
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
'src/**/*.{ts,tsx}',
|
'src/**/*.{ts,tsx}',
|
||||||
|
'!src/**/*.d.ts',
|
||||||
'!**/node_modules/**',
|
'!**/node_modules/**',
|
||||||
'!**/vendor/**',
|
'!**/vendor/**',
|
||||||
],
|
],
|
||||||
|
|||||||
@ -54,7 +54,7 @@ const LowcodeTypes: any = {
|
|||||||
(window as any).PropTypes = LowcodeTypes;
|
(window as any).PropTypes = LowcodeTypes;
|
||||||
(window as any).React.PropTypes = LowcodeTypes;
|
(window as any).React.PropTypes = LowcodeTypes;
|
||||||
|
|
||||||
// override primitive type chechers
|
// override primitive type checkers
|
||||||
primitiveTypes.forEach(type => {
|
primitiveTypes.forEach(type => {
|
||||||
const propType = (PropTypes as any)[type];
|
const propType = (PropTypes as any)[type];
|
||||||
if (!propType) {
|
if (!propType) {
|
||||||
|
|||||||
@ -68,7 +68,7 @@ export class SettingTopEntry implements SettingEntry {
|
|||||||
readonly designer: Designer;
|
readonly designer: Designer;
|
||||||
|
|
||||||
constructor(readonly editor: IEditor, readonly nodes: Node[]) {
|
constructor(readonly editor: IEditor, readonly nodes: Node[]) {
|
||||||
if (nodes.length < 1) {
|
if (!Array.isArray(nodes) || nodes.length < 1) {
|
||||||
throw new ReferenceError('nodes should not be empty');
|
throw new ReferenceError('nodes should not be empty');
|
||||||
}
|
}
|
||||||
this.id = generateSessionId(nodes);
|
this.id = generateSessionId(nodes);
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import '../fixtures/window';
|
||||||
|
import { parseMetadata } from '../../src/builtin-simulator/utils/parse-metadata';
|
||||||
|
|
||||||
|
describe('parseMetadata', () => {
|
||||||
|
it('parseMetadata', async () => {
|
||||||
|
console.log(parseMetadata('Div'))
|
||||||
|
console.log(parseMetadata({ componentName: 'Div' }));
|
||||||
|
});
|
||||||
|
});
|
||||||
78
packages/designer/tests/builtin-simulator/path.test.ts
Normal file
78
packages/designer/tests/builtin-simulator/path.test.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
generateComponentName,
|
||||||
|
getNormalizedImportPath,
|
||||||
|
isPackagePath,
|
||||||
|
toTitleCase,
|
||||||
|
makeRelativePath,
|
||||||
|
removeVersion,
|
||||||
|
resolveAbsoluatePath,
|
||||||
|
joinPath,
|
||||||
|
} from '../../src/builtin-simulator/utils/path';
|
||||||
|
|
||||||
|
describe('builtin-simulator/utils/path 测试', () => {
|
||||||
|
it('isPackagePath', () => {
|
||||||
|
expect(isPackagePath('a')).toBeTruthy;
|
||||||
|
expect(isPackagePath('@ali/a')).toBeTruthy;
|
||||||
|
expect(isPackagePath('@alife/a')).toBeTruthy;
|
||||||
|
expect(isPackagePath('a.b')).toBeTruthy;
|
||||||
|
expect(isPackagePath('./a')).toBeFalsy;
|
||||||
|
expect(isPackagePath('../a')).toBeFalsy;
|
||||||
|
expect(isPackagePath('/a')).toBeFalsy;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('toTitleCase', () => {
|
||||||
|
expect(toTitleCase('a')).toBe('A');
|
||||||
|
expect(toTitleCase('a_b')).toBe('AB');
|
||||||
|
expect(toTitleCase('a b')).toBe('AB');
|
||||||
|
expect(toTitleCase('a-b')).toBe('AB');
|
||||||
|
expect(toTitleCase('a.b')).toBe('AB');
|
||||||
|
expect(toTitleCase('a.b.cx')).toBe('ABCx');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generateComponentName', () => {
|
||||||
|
expect(generateComponentName('a/index.js')).toBe('A');
|
||||||
|
expect(generateComponentName('a_b/index.js')).toBe('AB');
|
||||||
|
expect(generateComponentName('a_b/index.web.js')).toBe('AB');
|
||||||
|
expect(generateComponentName('a_b/index.xxx.js')).toBe('AB');
|
||||||
|
expect(generateComponentName('a_b')).toBe('AB');
|
||||||
|
expect(generateComponentName('')).toBe('Component');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getNormalizedImportPath', () => {
|
||||||
|
expect(getNormalizedImportPath('/a')).toBe('/a');
|
||||||
|
expect(getNormalizedImportPath('/a/')).toBe('/a/');
|
||||||
|
expect(getNormalizedImportPath('/a/index.js')).toBe('/a');
|
||||||
|
expect(getNormalizedImportPath('/a/index.ts')).toBe('/a');
|
||||||
|
expect(getNormalizedImportPath('/a/index.jsx')).toBe('/a');
|
||||||
|
expect(getNormalizedImportPath('/a/index.tsx')).toBe('/a');
|
||||||
|
expect(getNormalizedImportPath('/a/index.x')).toBe('/a/index.x');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('makeRelativePath', () => {
|
||||||
|
expect(makeRelativePath('/a/b/c', '/a/b')).toBe('c');
|
||||||
|
expect(makeRelativePath('a/b/c', '/a/c')).toBe('a/b/c');
|
||||||
|
expect(makeRelativePath('/a/b/c', '/a/c')).toBe('./b/c');
|
||||||
|
expect(makeRelativePath('/a/b/c', '/a/c/d')).toBe('../b/c');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolveAbsoluatePath', () => {
|
||||||
|
expect(resolveAbsoluatePath('/a/b/c', '/a')).toBe('/a/b/c');
|
||||||
|
expect(resolveAbsoluatePath('@ali/fe', '/a')).toBe('@ali/fe');
|
||||||
|
expect(resolveAbsoluatePath('./a/b', '/c')).toBe('/c/a/b');
|
||||||
|
expect(resolveAbsoluatePath('./a/b/d', '/c')).toBe('/c/a/b/d');
|
||||||
|
expect(resolveAbsoluatePath('../a/b', '/c')).toBe('/a/b');
|
||||||
|
expect(resolveAbsoluatePath('../a/b/d', '/c')).toBe('/a/b/d');
|
||||||
|
expect(resolveAbsoluatePath('../../a', 'c')).toBe('../a');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('joinPath', () => {
|
||||||
|
expect(joinPath('/a', 'b', 'c')).toBe('/a/b/c');
|
||||||
|
expect(joinPath('a', 'b', 'c')).toBe('./a/b/c');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('removeVersion', () => {
|
||||||
|
expect(removeVersion('@ali/fe')).toBe('@ali/fe');
|
||||||
|
expect(removeVersion('@ali/fe@1.0.0/index')).toBe('@ali/fe/index');
|
||||||
|
expect(removeVersion('haha')).toBe('haha');
|
||||||
|
});
|
||||||
|
});
|
||||||
22
packages/designer/tests/builtin-simulator/throttle.test.ts
Normal file
22
packages/designer/tests/builtin-simulator/throttle.test.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import '../fixtures/disable-raf';
|
||||||
|
import { throttle } from '../../src/builtin-simulator/utils/throttle';
|
||||||
|
|
||||||
|
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
|
const cb = jest.fn();
|
||||||
|
|
||||||
|
describe('throttle', () => {
|
||||||
|
it('simple', async () => {
|
||||||
|
const fn = throttle(cb, 1000);
|
||||||
|
fn();
|
||||||
|
|
||||||
|
expect(cb).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
await delay(200);
|
||||||
|
fn();
|
||||||
|
|
||||||
|
await delay(400);
|
||||||
|
fn();
|
||||||
|
expect(cb).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -218,7 +218,10 @@ export default {
|
|||||||
],
|
],
|
||||||
component: {
|
component: {
|
||||||
isContainer: true,
|
isContainer: true,
|
||||||
nestingRule: {},
|
nestingRule: {
|
||||||
|
parentWhitelist: 'Div',
|
||||||
|
childWhitelist: 'Div',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
supports: {},
|
supports: {},
|
||||||
},
|
},
|
||||||
|
|||||||
3
packages/designer/tests/fixtures/disable-raf.ts
vendored
Normal file
3
packages/designer/tests/fixtures/disable-raf.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Object.defineProperty(window, 'requestAnimationFrame', {
|
||||||
|
value: null,
|
||||||
|
})
|
||||||
259
packages/designer/tests/fixtures/prototype/div-meta.ts
vendored
Normal file
259
packages/designer/tests/fixtures/prototype/div-meta.ts
vendored
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
export default {
|
||||||
|
componentName: 'Div',
|
||||||
|
title: '容器',
|
||||||
|
docUrl: 'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
|
||||||
|
devMode: 'procode',
|
||||||
|
tags: ['布局'],
|
||||||
|
configure: {
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'behavior',
|
||||||
|
title: '默认状态',
|
||||||
|
extraProps: {
|
||||||
|
display: 'inline',
|
||||||
|
defaultValue: 'NORMAL',
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
componentName: 'MixedSetter',
|
||||||
|
props: {
|
||||||
|
setters: [
|
||||||
|
{
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
title: '普通',
|
||||||
|
value: 'NORMAL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '隐藏',
|
||||||
|
value: 'HIDDEN',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
loose: false,
|
||||||
|
cancelable: false,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
'VariableSetter',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: '__style__',
|
||||||
|
title: {
|
||||||
|
label: '样式设置',
|
||||||
|
tip: '点击 ? 查看样式设置器用法指南',
|
||||||
|
docUrl: 'https://lark.alipay.com/legao/help/design-tool-style',
|
||||||
|
},
|
||||||
|
extraProps: {
|
||||||
|
display: 'accordion',
|
||||||
|
defaultValue: {},
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
advanced: true,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
name: 'groupkh97h5kc',
|
||||||
|
title: '高级',
|
||||||
|
extraProps: {
|
||||||
|
display: 'accordion',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'fieldId',
|
||||||
|
title: {
|
||||||
|
label: '唯一标识',
|
||||||
|
},
|
||||||
|
extraProps: {
|
||||||
|
display: 'block',
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
placeholder: '请输入唯一标识',
|
||||||
|
multiline: false,
|
||||||
|
rows: 10,
|
||||||
|
required: false,
|
||||||
|
pattern: null,
|
||||||
|
maxLength: null,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'useFieldIdAsDomId',
|
||||||
|
title: {
|
||||||
|
label: '将唯一标识用作 DOM ID',
|
||||||
|
},
|
||||||
|
extraProps: {
|
||||||
|
display: 'block',
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'customClassName',
|
||||||
|
title: '自定义样式类',
|
||||||
|
extraProps: {
|
||||||
|
display: 'block',
|
||||||
|
defaultValue: '',
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
componentName: 'MixedSetter',
|
||||||
|
props: {
|
||||||
|
setters: [
|
||||||
|
{
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
placeholder: null,
|
||||||
|
multiline: false,
|
||||||
|
rows: 10,
|
||||||
|
required: false,
|
||||||
|
pattern: null,
|
||||||
|
maxLength: null,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
'VariableSetter',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'events',
|
||||||
|
title: {
|
||||||
|
label: '动作设置',
|
||||||
|
tip: '点击 ? 查看如何设置组件的事件响应动作',
|
||||||
|
docUrl: 'https://lark.alipay.com/legao/legao/events-call',
|
||||||
|
},
|
||||||
|
extraProps: {
|
||||||
|
display: 'accordion',
|
||||||
|
defaultValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
events: [
|
||||||
|
{
|
||||||
|
name: 'onClick',
|
||||||
|
title: '当点击时',
|
||||||
|
initialValue:
|
||||||
|
"/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseEnter',
|
||||||
|
title: '当鼠标进入时',
|
||||||
|
initialValue:
|
||||||
|
"/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseLeave',
|
||||||
|
title: '当鼠标离开时',
|
||||||
|
initialValue:
|
||||||
|
"/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'onClick',
|
||||||
|
extraProps: {
|
||||||
|
defaultValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setter: 'I18nSetter',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'onMouseEnter',
|
||||||
|
extraProps: {
|
||||||
|
defaultValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setter: 'I18nSetter',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
name: 'onMouseLeave',
|
||||||
|
extraProps: {
|
||||||
|
defaultValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setter: 'I18nSetter',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
component: {
|
||||||
|
isContainer: true,
|
||||||
|
nestingRule: {},
|
||||||
|
},
|
||||||
|
supports: {},
|
||||||
|
},
|
||||||
|
experimental: {
|
||||||
|
callbacks: {},
|
||||||
|
initials: [
|
||||||
|
{
|
||||||
|
name: 'behavior',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '__style__',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fieldId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'useFieldIdAsDomId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'customClassName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'events',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onClick',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseEnter',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseLeave',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
filters: [],
|
||||||
|
autoruns: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
90
packages/designer/tests/fixtures/schema/setting.ts
vendored
Normal file
90
packages/designer/tests/fixtures/schema/setting.ts
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
export default {
|
||||||
|
componentName: 'Page',
|
||||||
|
id: 'node_k1ow3cb9',
|
||||||
|
title: 'hey, i\' a page!',
|
||||||
|
props: {
|
||||||
|
extensions: {
|
||||||
|
启用页头: true,
|
||||||
|
},
|
||||||
|
pageStyle: {
|
||||||
|
backgroundColor: '#f2f3f5',
|
||||||
|
},
|
||||||
|
containerStyle: {},
|
||||||
|
className: 'page_kgaqfbm4',
|
||||||
|
templateVersion: '1.0.0',
|
||||||
|
},
|
||||||
|
lifeCycles: {
|
||||||
|
constructor: {
|
||||||
|
type: 'js',
|
||||||
|
compiled:
|
||||||
|
"function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",
|
||||||
|
source:
|
||||||
|
"function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
condition: true,
|
||||||
|
css:
|
||||||
|
'body{background-color:#f2f3f5}.card_kgaqfbm5 {\n margin-bottom: 12px;\n}.card_kgaqfbm6 {\n margin-bottom: 12px;\n}.button_kgaqfbm7 {\n margin-right: 16px;\n width: 80px\n}.button_kgaqfbm8 {\n width: 80px;\n}.div_kgaqfbm9 {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n background: #fff;\n padding: 20px 0;\n}',
|
||||||
|
methods: {
|
||||||
|
__initMethods__: {
|
||||||
|
type: 'js',
|
||||||
|
source: 'function (exports, module) { /*set actions code here*/ }',
|
||||||
|
compiled: 'function (exports, module) { /*set actions code here*/ }',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Div',
|
||||||
|
id: 'div',
|
||||||
|
props: {
|
||||||
|
className: 'div_kgaqfbm9',
|
||||||
|
behavior: 'NORMAL',
|
||||||
|
__style__:
|
||||||
|
':root {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n background: #fff;\n padding: 20px 0;\n}',
|
||||||
|
events: {},
|
||||||
|
fieldId: 'div_k1ow3h1o',
|
||||||
|
useFieldIdAsDomId: false,
|
||||||
|
customClassName: {
|
||||||
|
type: 'JSExpression',
|
||||||
|
value: 'getFromSomewhere()'
|
||||||
|
},
|
||||||
|
customClassName2: {
|
||||||
|
type: 'JSExpression',
|
||||||
|
mock: { hi: 'mock' },
|
||||||
|
value: 'getFromSomewhere()'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraPropA: 'haha',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Div',
|
||||||
|
id: 'div2',
|
||||||
|
props: {
|
||||||
|
className: 'div_kgaqfbm9',
|
||||||
|
behavior: 'NORMAL',
|
||||||
|
__style__:
|
||||||
|
':root {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n background: #fff;\n padding: 20px 0;\n}',
|
||||||
|
events: {},
|
||||||
|
fieldId: 'div_k1ow3h1o',
|
||||||
|
useFieldIdAsDomId: false,
|
||||||
|
customClassName: '',
|
||||||
|
},
|
||||||
|
extraPropA: 'haha',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Test',
|
||||||
|
id: 'test',
|
||||||
|
props: {
|
||||||
|
className: 'div_kgaqfbm9',
|
||||||
|
behavior: 'NORMAL',
|
||||||
|
__style__:
|
||||||
|
':root {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n background: #fff;\n padding: 20px 0;\n}',
|
||||||
|
events: {},
|
||||||
|
fieldId: 'div_k1ow3h1o',
|
||||||
|
useFieldIdAsDomId: false,
|
||||||
|
customClassName: '',
|
||||||
|
},
|
||||||
|
extraPropA: 'haha',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
};
|
||||||
@ -4,7 +4,7 @@ import '../fixtures/window';
|
|||||||
import { Node } from '../../src/document/node/node';
|
import { Node } from '../../src/document/node/node';
|
||||||
import { Designer } from '../../src/designer/designer';
|
import { Designer } from '../../src/designer/designer';
|
||||||
import divMeta from '../fixtures/component-metadata/div';
|
import divMeta from '../fixtures/component-metadata/div';
|
||||||
import { ComponentMeta } from '../../src/component-meta';
|
import { ComponentMeta, isComponentMeta, removeBuiltinComponentAction, addBuiltinComponentAction } from '../../src/component-meta';
|
||||||
|
|
||||||
const mockCreateSettingEntry = jest.fn();
|
const mockCreateSettingEntry = jest.fn();
|
||||||
jest.mock('../../src/designer/designer', () => {
|
jest.mock('../../src/designer/designer', () => {
|
||||||
@ -25,6 +25,47 @@ beforeAll(() => {
|
|||||||
describe('组件元数据处理', () => {
|
describe('组件元数据处理', () => {
|
||||||
it('构造函数', () => {
|
it('构造函数', () => {
|
||||||
const meta = new ComponentMeta(designer, divMeta);
|
const meta = new ComponentMeta(designer, divMeta);
|
||||||
console.log(meta);
|
expect(meta.isContainer).toBeTruthy;
|
||||||
|
expect(isComponentMeta(meta)).toBeTruthy;
|
||||||
|
expect(meta.acceptable).toBeTruthy;
|
||||||
|
expect(meta.isRootComponent()).toBeTruthy;
|
||||||
|
expect(meta.isModal).toBeFalsy;
|
||||||
|
expect(meta.rootSelector).toBeUndefined;
|
||||||
|
expect(meta.liveTextEditing).toBeUndefined;
|
||||||
|
expect(meta.descriptor).toBeUndefined;
|
||||||
|
expect(meta.icon).toBeUndefined;
|
||||||
|
expect(meta.getMetadata().title).toBe('容器');
|
||||||
|
expect(meta.title).toEqual({ type: 'i18n', 'en-US': 'Div', 'zh-CN': '容器' });
|
||||||
|
|
||||||
|
meta.setNpm({ package: '@ali/vc-div', componentName: 'Div' });
|
||||||
|
expect(meta.npm).toEqual({ package: '@ali/vc-div', componentName: 'Div' });
|
||||||
|
|
||||||
|
meta.setMetadata(divMeta);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('availableActions', () => {
|
||||||
|
const meta = new ComponentMeta(designer, divMeta);
|
||||||
|
expect(meta.availableActions).toHaveLength(3);
|
||||||
|
expect(meta.availableActions[0].name).toBe('remove');
|
||||||
|
expect(meta.availableActions[1].name).toBe('hide');
|
||||||
|
expect(meta.availableActions[2].name).toBe('copy');
|
||||||
|
|
||||||
|
removeBuiltinComponentAction('remove');
|
||||||
|
// availableActions 有 computed 缓存
|
||||||
|
expect(meta.availableActions[0].name).toBe('remove');
|
||||||
|
expect(meta.availableActions[1].name).toBe('hide');
|
||||||
|
expect(meta.availableActions[2].name).toBe('copy');
|
||||||
|
|
||||||
|
addBuiltinComponentAction({
|
||||||
|
name: 'new',
|
||||||
|
content: {
|
||||||
|
action() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// availableActions 有 computed 缓存
|
||||||
|
expect(meta.availableActions).toHaveLength(3);
|
||||||
|
expect(meta.availableActions[0].name).toBe('remove');
|
||||||
|
expect(meta.availableActions[1].name).toBe('hide');
|
||||||
|
expect(meta.availableActions[2].name).toBe('copy');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
105
packages/designer/tests/setting-entry/setting-prop-entry.test.ts
Normal file
105
packages/designer/tests/setting-entry/setting-prop-entry.test.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import set from 'lodash/set';
|
||||||
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
|
import '../fixtures/window';
|
||||||
|
import { Editor } from '@ali/lowcode-editor-core';
|
||||||
|
import { Project } from '../../src/project/project';
|
||||||
|
import { Node } from '../../src/document/node/node';
|
||||||
|
import { Designer } from '../../src/designer/designer';
|
||||||
|
import formSchema from '../fixtures/schema/form';
|
||||||
|
import settingSchema from '../fixtures/schema/setting';
|
||||||
|
import divMeta from '../fixtures/prototype/div-meta';
|
||||||
|
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
||||||
|
|
||||||
|
const editor = new Editor();
|
||||||
|
|
||||||
|
describe('setting-prop-entry 测试', () => {
|
||||||
|
let designer: Designer;
|
||||||
|
beforeEach(() => {
|
||||||
|
designer = new Designer({ editor });
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
designer._componentMetasMap.clear();
|
||||||
|
designer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('node 构造函数生成 settingEntry', () => {
|
||||||
|
it.only('常规方法测试', () => {
|
||||||
|
designer.createComponentMeta(divMeta);
|
||||||
|
designer.project.open(settingSchema);
|
||||||
|
const { currentDocument } = designer.project;
|
||||||
|
const divNode = currentDocument?.getNode('div');
|
||||||
|
|
||||||
|
const { settingEntry } = divNode!;
|
||||||
|
const behaviorProp = settingEntry.getProp('behavior');
|
||||||
|
expect(behaviorProp.getProps()).toBe(settingEntry);
|
||||||
|
expect(behaviorProp.props).toBe(settingEntry);
|
||||||
|
expect(behaviorProp.getName()).toBe('behavior');
|
||||||
|
expect(behaviorProp.getKey()).toBe('behavior');
|
||||||
|
expect(behaviorProp.isIgnore()).toBeFalsy;
|
||||||
|
behaviorProp.setKey('behavior2');
|
||||||
|
expect(behaviorProp.getKey()).toBe('behavior2');
|
||||||
|
behaviorProp.setKey('behavior');
|
||||||
|
expect(behaviorProp.getValue()).toBe('NORMAL');
|
||||||
|
expect(behaviorProp.getMockOrValue()).toBe('NORMAL');
|
||||||
|
|
||||||
|
behaviorProp.setValue('LARGE');
|
||||||
|
expect(behaviorProp.getValue()).toBe('LARGE');
|
||||||
|
// behaviorProp.setPropValue('behavior', 'SMALL');
|
||||||
|
// expect(behaviorProp.getValue()).toBe('SMALL');
|
||||||
|
behaviorProp.setValue('NORMAL');
|
||||||
|
expect(behaviorProp.getValue()).toBe('NORMAL');
|
||||||
|
|
||||||
|
behaviorProp.clearValue();
|
||||||
|
behaviorProp.clearPropValue();
|
||||||
|
expect(settingEntry.getProp('behavior').getValue()).toBeUndefined;
|
||||||
|
|
||||||
|
behaviorProp.setValue('LARGE');
|
||||||
|
expect(behaviorProp.getValue()).toBe('LARGE');
|
||||||
|
behaviorProp.remove();
|
||||||
|
expect(settingEntry.getProp('behavior').getValue()).toBeUndefined;
|
||||||
|
|
||||||
|
expect(behaviorProp.getNode()).toBe(divNode);
|
||||||
|
expect(behaviorProp.getId().startsWith('entry')).toBeTruthy;
|
||||||
|
expect(behaviorProp.designer).toBe(designer);
|
||||||
|
expect(behaviorProp.isSingle).toBeTruthy;
|
||||||
|
expect(behaviorProp.isMultiple).toBeFalsy;
|
||||||
|
expect(behaviorProp.isGroup).toBeFalsy;
|
||||||
|
expect(behaviorProp.isSameComponent).toBeTruthy;
|
||||||
|
expect(typeof settingEntry.getValue).toBe('function');
|
||||||
|
settingEntry.getValue();
|
||||||
|
|
||||||
|
behaviorProp.setExtraPropValue('extraPropA', 'heihei');
|
||||||
|
expect(behaviorProp.getExtraPropValue('extraPropA', 'heihei'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('type: group 场景测试', () => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('JSExpression 类型的 prop', () => {
|
||||||
|
designer.createComponentMeta(divMeta);
|
||||||
|
designer.project.open(settingSchema);
|
||||||
|
const { currentDocument } = designer.project;
|
||||||
|
const divNode = currentDocument?.getNode('div');
|
||||||
|
|
||||||
|
const { settingEntry } = divNode!;
|
||||||
|
const customClassNameProp = settingEntry.getProp('customClassName');
|
||||||
|
expect(customClassNameProp.isUseVariable()).toBeTruthy;
|
||||||
|
expect(customClassNameProp.useVariable).toBeTruthy;
|
||||||
|
|
||||||
|
expect(customClassNameProp.getValue()).toEqual({
|
||||||
|
type: 'JSExpression',
|
||||||
|
value: 'getFromSomewhere()'
|
||||||
|
});
|
||||||
|
expect(customClassNameProp.getMockOrValue()).toBeUndefined;
|
||||||
|
expect(customClassNameProp.getVariableValue()).toBe('getFromSomewhere()');
|
||||||
|
customClassNameProp.setVariableValue('xxx');
|
||||||
|
expect(customClassNameProp.getVariableValue()).toBe('xxx');
|
||||||
|
|
||||||
|
const customClassName2Prop = settingEntry.getProp('customClassName2');
|
||||||
|
expect(customClassName2Prop.getMockOrValue()).toEqual({
|
||||||
|
hi: 'mock',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
174
packages/designer/tests/setting-entry/setting-top-entry.test.ts
Normal file
174
packages/designer/tests/setting-entry/setting-top-entry.test.ts
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
import set from 'lodash/set';
|
||||||
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
|
import '../fixtures/window';
|
||||||
|
import { Editor } from '@ali/lowcode-editor-core';
|
||||||
|
import { Project } from '../../src/project/project';
|
||||||
|
import { Node } from '../../src/document/node/node';
|
||||||
|
import { Designer } from '../../src/designer/designer';
|
||||||
|
import formSchema from '../fixtures/schema/form';
|
||||||
|
import settingSchema from '../fixtures/schema/setting';
|
||||||
|
import divMeta from '../fixtures/prototype/div-meta';
|
||||||
|
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
||||||
|
|
||||||
|
const editor = new Editor();
|
||||||
|
|
||||||
|
describe('setting-top-entry 测试', () => {
|
||||||
|
let designer: Designer;
|
||||||
|
beforeEach(() => {
|
||||||
|
designer = new Designer({ editor });
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
designer._componentMetasMap.clear();
|
||||||
|
designer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('node 构造函数生成 settingEntry', () => {
|
||||||
|
it('常规方法测试', () => {
|
||||||
|
designer.createComponentMeta(divMeta);
|
||||||
|
designer.project.open(settingSchema);
|
||||||
|
const { currentDocument } = designer.project;
|
||||||
|
const divNode = currentDocument?.getNode('div');
|
||||||
|
|
||||||
|
const { settingEntry } = divNode!;
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBe('NORMAL');
|
||||||
|
expect(settingEntry.getProp('behavior').getValue()).toBe('NORMAL');
|
||||||
|
settingEntry.setPropValue('behavior', 'LARGE');
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBe('LARGE');
|
||||||
|
expect(settingEntry.get('behavior').getValue()).toBe('LARGE');
|
||||||
|
settingEntry.getProp('behavior').setValue('SMALL');
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBe('SMALL');
|
||||||
|
settingEntry.clearPropValue('behavior');
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBeUndefined;
|
||||||
|
|
||||||
|
expect(settingEntry.getPropValue('fieldId')).toBe('div_k1ow3h1o');
|
||||||
|
settingEntry.setPropValue('fieldId', 'div_k1ow3h1o_new');
|
||||||
|
expect(settingEntry.getPropValue('fieldId')).toBe('div_k1ow3h1o_new');
|
||||||
|
|
||||||
|
expect(settingEntry.getExtraPropValue('extraPropA')).toBe('haha');
|
||||||
|
settingEntry.setExtraPropValue('extraPropA', 'haha2');
|
||||||
|
expect(settingEntry.getExtraPropValue('extraPropA')).toBe('haha2');
|
||||||
|
|
||||||
|
settingEntry.mergeProps({
|
||||||
|
newPropA: 'haha',
|
||||||
|
});
|
||||||
|
expect(settingEntry.getPropValue('newPropA')).toBe('haha');
|
||||||
|
settingEntry.setProps({
|
||||||
|
newPropB: 'haha',
|
||||||
|
});
|
||||||
|
expect(settingEntry.getPropValue('newPropB')).toBe('haha');
|
||||||
|
settingEntry.setValue({
|
||||||
|
newPropC: 'haha',
|
||||||
|
});
|
||||||
|
expect(settingEntry.getPropValue('newPropC')).toBe('haha');
|
||||||
|
|
||||||
|
expect(settingEntry.getPage()).toBe(currentDocument);
|
||||||
|
expect(settingEntry.getNode()).toBe(divNode);
|
||||||
|
expect(settingEntry.node).toBe(divNode);
|
||||||
|
expect(settingEntry.getId()).toBe('div');
|
||||||
|
expect(settingEntry.first).toBe(divNode);
|
||||||
|
expect(settingEntry.designer).toBe(designer);
|
||||||
|
expect(settingEntry.isSingle).toBeTruthy;
|
||||||
|
expect(settingEntry.isMultiple).toBeFalsy;
|
||||||
|
expect(settingEntry.isSameComponent).toBeTruthy;
|
||||||
|
|
||||||
|
expect(typeof settingEntry.getValue).toBe('function');
|
||||||
|
settingEntry.getValue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('清理方法测试', () => {
|
||||||
|
designer.createComponentMeta(divMeta);
|
||||||
|
designer.project.open(settingSchema);
|
||||||
|
const { currentDocument } = designer.project;
|
||||||
|
const divNode = currentDocument?.getNode('div');
|
||||||
|
|
||||||
|
const { settingEntry } = divNode!;
|
||||||
|
expect(settingEntry.items).toHaveLength(3);
|
||||||
|
settingEntry.purge();
|
||||||
|
expect(settingEntry.items).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('vision 兼容测试', () => {
|
||||||
|
designer.createComponentMeta(divMeta);
|
||||||
|
designer.project.open(settingSchema);
|
||||||
|
const { currentDocument } = designer.project;
|
||||||
|
const divNode = currentDocument?.getNode('div');
|
||||||
|
|
||||||
|
console.log(divNode?.getPropValue('behavior'));
|
||||||
|
const { settingEntry } = divNode!;
|
||||||
|
|
||||||
|
expect(typeof settingEntry.getChildren).toBe('function');
|
||||||
|
expect(typeof settingEntry.getDOMNode).toBe('function');
|
||||||
|
expect(typeof settingEntry.getStatus).toBe('function');
|
||||||
|
expect(typeof settingEntry.setStatus).toBe('function');
|
||||||
|
settingEntry.getStatus();
|
||||||
|
settingEntry.setStatus();
|
||||||
|
settingEntry.getChildren();
|
||||||
|
settingEntry.getDOMNode();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('没有 node', () => {
|
||||||
|
const create1 = designer.createSettingEntry.bind(designer);
|
||||||
|
const create2 = designer.createSettingEntry.bind(designer, []);
|
||||||
|
expect(create1).toThrowError('nodes should not be empty');
|
||||||
|
expect(create2).toThrowError('nodes should not be empty');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('designer.createSettingEntry 生成 settingEntry(多 node 场景)', () => {
|
||||||
|
it('相同类型的 node', () => {
|
||||||
|
designer.project.open(settingSchema);
|
||||||
|
const { currentDocument } = designer.project;
|
||||||
|
const divNode = currentDocument?.getNode('div');
|
||||||
|
const divNode2 = currentDocument?.getNode('div2');
|
||||||
|
const settingEntry = designer.createSettingEntry([divNode, divNode2]);
|
||||||
|
|
||||||
|
expect(settingEntry.isMultiple).toBeTruthy;
|
||||||
|
expect(settingEntry.isSameComponent).toBeTruthy;
|
||||||
|
expect(settingEntry.isSingle).toBeFalsy;
|
||||||
|
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBe('NORMAL');
|
||||||
|
expect(settingEntry.getProp('behavior').getValue()).toBe('NORMAL');
|
||||||
|
settingEntry.setPropValue('behavior', 'LARGE');
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBe('LARGE');
|
||||||
|
expect(settingEntry.get('behavior').getValue()).toBe('LARGE');
|
||||||
|
// 多个 node 都被成功设值
|
||||||
|
expect(divNode?.getPropValue('behavior')).toBe('LARGE');
|
||||||
|
expect(divNode2?.getPropValue('behavior')).toBe('LARGE');
|
||||||
|
|
||||||
|
settingEntry.getProp('behavior').setValue('SMALL');
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBe('SMALL');
|
||||||
|
// 多个 node 都被成功设值
|
||||||
|
expect(divNode?.getPropValue('behavior')).toBe('SMALL');
|
||||||
|
expect(divNode2?.getPropValue('behavior')).toBe('SMALL');
|
||||||
|
|
||||||
|
settingEntry.clearPropValue('behavior');
|
||||||
|
expect(settingEntry.getPropValue('behavior')).toBeUndefined;
|
||||||
|
// 多个 node 都被成功设值
|
||||||
|
expect(divNode?.getPropValue('behavior')).toBeUndefined;
|
||||||
|
expect(divNode2?.getPropValue('behavior')).toBeUndefined;
|
||||||
|
|
||||||
|
expect(settingEntry.getPropValue('fieldId')).toBe('div_k1ow3h1o');
|
||||||
|
settingEntry.setPropValue('fieldId', 'div_k1ow3h1o_new');
|
||||||
|
expect(settingEntry.getPropValue('fieldId')).toBe('div_k1ow3h1o_new');
|
||||||
|
|
||||||
|
expect(settingEntry.getExtraPropValue('extraPropA')).toBe('haha');
|
||||||
|
settingEntry.setExtraPropValue('extraPropA', 'haha2');
|
||||||
|
expect(settingEntry.getExtraPropValue('extraPropA')).toBe('haha2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('不同类型的 node', () => {
|
||||||
|
designer.project.open(settingSchema);
|
||||||
|
const { currentDocument } = designer.project;
|
||||||
|
const divNode = currentDocument?.getNode('div');
|
||||||
|
const testNode = currentDocument?.getNode('test');
|
||||||
|
const settingEntry = designer.createSettingEntry([divNode, testNode]);
|
||||||
|
|
||||||
|
expect(settingEntry.isMultiple).toBeTruthy;
|
||||||
|
expect(settingEntry.isSameComponent).toBeFalsy;
|
||||||
|
expect(settingEntry.isSingle).toBeFalsy;
|
||||||
|
|
||||||
|
// 不同类型的 node 场景下,理论上从页面上已没有修改属性的方法调用,所以此处不再断言各设值方法
|
||||||
|
// 思考:假如以后面向其他场景,比如用户用 API 强行调用,是否需要做健壮性保护?
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -17,6 +17,9 @@ module.exports = {
|
|||||||
collectCoverage: false,
|
collectCoverage: false,
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
'src/**/*.{ts,tsx}',
|
'src/**/*.{ts,tsx}',
|
||||||
|
'!src/**/*.d.ts',
|
||||||
|
'!src/base/**',
|
||||||
|
'!src/prop.ts',
|
||||||
'!**/node_modules/**',
|
'!**/node_modules/**',
|
||||||
'!**/vendor/**',
|
'!**/vendor/**',
|
||||||
],
|
],
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import logger from '@ali/vu-logger';
|
|||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import I18nUtil from './i18n-util';
|
import I18nUtil from './i18n-util';
|
||||||
import { hotkey as Hotkey, monitor } from '@ali/lowcode-editor-core';
|
import { hotkey as Hotkey, monitor } from '@ali/lowcode-editor-core';
|
||||||
|
import { registerMetadataTransducer } from '@ali/lowcode-designer';
|
||||||
import { createElement } from 'react';
|
import { createElement } from 'react';
|
||||||
import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS, VERSION as Version } from './base/const';
|
import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS, VERSION as Version } from './base/const';
|
||||||
import Bus from './bus';
|
import Bus from './bus';
|
||||||
@ -110,6 +111,7 @@ const VisualEngine = {
|
|||||||
Project,
|
Project,
|
||||||
logger,
|
logger,
|
||||||
Symbols,
|
Symbols,
|
||||||
|
registerMetadataTransducer,
|
||||||
// Flags,
|
// Flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -160,6 +162,7 @@ export {
|
|||||||
Project,
|
Project,
|
||||||
logger,
|
logger,
|
||||||
Symbols,
|
Symbols,
|
||||||
|
registerMetadataTransducer,
|
||||||
};
|
};
|
||||||
|
|
||||||
const version = '6.0.0 (LowcodeEngine 0.9.32)';
|
const version = '6.0.0 (LowcodeEngine 0.9.32)';
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { isJSExpression, isJSBlock, isJSSlot } from '@ali/lowcode-types';
|
|||||||
import { isVariable, getCurrentFieldIds } from '../utils';
|
import { isVariable, getCurrentFieldIds } from '../utils';
|
||||||
|
|
||||||
export function initNodeReducer(props, node) {
|
export function initNodeReducer(props, node) {
|
||||||
// debugger;
|
|
||||||
// run initials
|
// run initials
|
||||||
const newProps: any = {
|
const newProps: any = {
|
||||||
...props,
|
...props,
|
||||||
@ -23,6 +22,7 @@ export function initNodeReducer(props, node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const initials = node.componentMeta.getMetadata().experimental?.initials;
|
const initials = node.componentMeta.getMetadata().experimental?.initials;
|
||||||
|
|
||||||
if (initials) {
|
if (initials) {
|
||||||
const getRealValue = (propValue: any) => {
|
const getRealValue = (propValue: any) => {
|
||||||
if (isVariable(propValue)) {
|
if (isVariable(propValue)) {
|
||||||
|
|||||||
116
packages/editor-preset-vision/tests/bundle/bundle.test.ts
Normal file
116
packages/editor-preset-vision/tests/bundle/bundle.test.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
import set from 'lodash/set';
|
||||||
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
|
import '../fixtures/window';
|
||||||
|
import divPrototypeConfig from '../fixtures/prototype/div-vision';
|
||||||
|
import trunk from '../../src/bundle/trunk';
|
||||||
|
import Prototype from '../../src/bundle/prototype';
|
||||||
|
import Bundle from '../../src/bundle/bundle';
|
||||||
|
import { Editor } from '@ali/lowcode-editor-core';
|
||||||
|
|
||||||
|
jest.mock('../../src/bundle/trunk', () => {
|
||||||
|
// mockComponentPrototype = jest.fn();
|
||||||
|
// return {
|
||||||
|
// mockComponentPrototype: jest.fn().mockImplementation(() => {
|
||||||
|
// return proto;
|
||||||
|
// }),
|
||||||
|
// }
|
||||||
|
// return jest.fn().mockImplementation(() => {
|
||||||
|
// return {playSoundFile: fakePlaySoundFile};
|
||||||
|
// });
|
||||||
|
// return jest.fn().mockImplementation(() => {
|
||||||
|
// return { mockComponentPrototype };
|
||||||
|
// });
|
||||||
|
return {
|
||||||
|
__esModule: true,
|
||||||
|
default: {
|
||||||
|
mockComponentPrototype: jest.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
function wrap(name, thing) {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
componentName: name,
|
||||||
|
category: '布局',
|
||||||
|
module: thing,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const proto1 = new Prototype(divPrototypeConfig);
|
||||||
|
const protoConfig2 = cloneDeep(divPrototypeConfig);
|
||||||
|
set(protoConfig2, 'componentName', 'Div2');
|
||||||
|
const proto2 = new Prototype(protoConfig2);
|
||||||
|
|
||||||
|
const protoConfig3 = cloneDeep(divPrototypeConfig);
|
||||||
|
set(protoConfig3, 'componentName', 'Div3');
|
||||||
|
const proto3 = new Prototype(protoConfig3);
|
||||||
|
|
||||||
|
const protoConfig4 = cloneDeep(divPrototypeConfig);
|
||||||
|
set(protoConfig4, 'componentName', 'Div4');
|
||||||
|
const proto4 = new Prototype(protoConfig4);
|
||||||
|
|
||||||
|
const protoConfig5 = cloneDeep(divPrototypeConfig);
|
||||||
|
set(protoConfig5, 'componentName', 'Div5');
|
||||||
|
const proto5 = new Prototype(protoConfig5);
|
||||||
|
|
||||||
|
function getComponentProtos() {
|
||||||
|
return [
|
||||||
|
wrap('Div', proto1),
|
||||||
|
// wrap('Div2', proto2),
|
||||||
|
// wrap('Div3', proto3),
|
||||||
|
wrap('DivPortal', [proto2, proto3]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Div extends Component {}
|
||||||
|
Div.displayName = 'Div';
|
||||||
|
class Div2 extends Component {}
|
||||||
|
Div2.displayName = 'Div2';
|
||||||
|
class Div3 extends Component {}
|
||||||
|
Div3.displayName = 'Div3';
|
||||||
|
class Div4 extends Component {}
|
||||||
|
Div4.displayName = 'Div4';
|
||||||
|
class Div5 extends Component {}
|
||||||
|
Div5.displayName = 'Div5';
|
||||||
|
|
||||||
|
function getComponentViews() {
|
||||||
|
return [
|
||||||
|
wrap('Div', Div),
|
||||||
|
// wrap('Div2', Div2),
|
||||||
|
// wrap('Div3', Div3),
|
||||||
|
wrap('DivPortal', [Div2, Div3]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Bundle', () => {
|
||||||
|
it('构造函数', () => {
|
||||||
|
const protos = getComponentProtos();
|
||||||
|
const views = getComponentViews();
|
||||||
|
const bundle = new Bundle(protos, views);
|
||||||
|
expect(bundle.getList()).toHaveLength(3);
|
||||||
|
expect(bundle.get('Div')).toBe(proto1);
|
||||||
|
expect(bundle.get('Div2')).toBe(proto2);
|
||||||
|
expect(bundle.get('Div3')).toBe(proto3);
|
||||||
|
bundle.addComponentBundle([proto4, Div4]);
|
||||||
|
expect(bundle.getList()).toHaveLength(4);
|
||||||
|
expect(bundle.get('Div4')).toBe(proto4);
|
||||||
|
bundle.replacePrototype('Div4', proto3);
|
||||||
|
expect(proto3.getView()).toBe(Div4);
|
||||||
|
|
||||||
|
bundle.removeComponentBundle('Div2');
|
||||||
|
expect(bundle.getList()).toHaveLength(3);
|
||||||
|
expect(bundle.get('Div2')).toBeUndefined;
|
||||||
|
|
||||||
|
expect(bundle.getFromMeta('Div')).toBe(proto1);
|
||||||
|
bundle.getFromMeta('Div5');
|
||||||
|
expect(bundle.getList()).toHaveLength(4);
|
||||||
|
});
|
||||||
|
it('静态方法 create', () => {
|
||||||
|
const protos = getComponentProtos();
|
||||||
|
const views = getComponentViews();
|
||||||
|
const bundle = Bundle.create(protos, views);
|
||||||
|
expect(bundle).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -6,6 +6,7 @@ import '../fixtures/window';
|
|||||||
// import { Node } from '../../src/document/node/node';
|
// import { Node } from '../../src/document/node/node';
|
||||||
// import { Designer } from '../../src/designer/designer';
|
// import { Designer } from '../../src/designer/designer';
|
||||||
import divPrototypeConfig from '../fixtures/prototype/div-vision';
|
import divPrototypeConfig from '../fixtures/prototype/div-vision';
|
||||||
|
import divFullPrototypeConfig from '../fixtures/prototype/div-vision-full';
|
||||||
import divPrototypeMeta from '../fixtures/prototype/div-meta';
|
import divPrototypeMeta from '../fixtures/prototype/div-meta';
|
||||||
// import VisualEngine from '../../src';
|
// import VisualEngine from '../../src';
|
||||||
import { designer } from '../../src/editor';
|
import { designer } from '../../src/editor';
|
||||||
@ -29,6 +30,21 @@ describe('Prototype', () => {
|
|||||||
expect(proto.isContainer()).toBeTruthy;
|
expect(proto.isContainer()).toBeTruthy;
|
||||||
expect(proto.isModal()).toBeFalsy;
|
expect(proto.isModal()).toBeFalsy;
|
||||||
});
|
});
|
||||||
|
it('构造函数 - 全量 OldPrototypeConfig', () => {
|
||||||
|
const proto = new Prototype(divFullPrototypeConfig);
|
||||||
|
expect(isPrototype(proto)).toBeTruthy;
|
||||||
|
expect(proto.getComponentName()).toBe('Div');
|
||||||
|
expect(proto.getId()).toBe('Div');
|
||||||
|
expect(proto.getCategory()).toBe('布局');
|
||||||
|
expect(proto.getDocUrl()).toBe(
|
||||||
|
'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
|
||||||
|
);
|
||||||
|
expect(proto.getIcon()).toBeUndefined;
|
||||||
|
expect(proto.getTitle()).toBe('Div');
|
||||||
|
expect(proto.isPrototype).toBeTruthy;
|
||||||
|
expect(proto.isContainer()).toBeTruthy;
|
||||||
|
expect(proto.isModal()).toBeFalsy;
|
||||||
|
});
|
||||||
it('构造函数 - ComponentMetadata', () => {
|
it('构造函数 - ComponentMetadata', () => {
|
||||||
const proto = new Prototype(divPrototypeMeta);
|
const proto = new Prototype(divPrototypeMeta);
|
||||||
expect(proto.getComponentName()).toBe('Div');
|
expect(proto.getComponentName()).toBe('Div');
|
||||||
|
|||||||
111
packages/editor-preset-vision/tests/bundle/trunk.test.ts
Normal file
111
packages/editor-preset-vision/tests/bundle/trunk.test.ts
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
import set from 'lodash/set';
|
||||||
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
|
import '../fixtures/window';
|
||||||
|
import divPrototypeConfig from '../fixtures/prototype/div-vision';
|
||||||
|
import Prototype from '../../src/bundle/prototype';
|
||||||
|
import Bundle from '../../src/bundle/bundle';
|
||||||
|
import trunk from '../../src/bundle/trunk';
|
||||||
|
import lg from '@ali/vu-logger';
|
||||||
|
|
||||||
|
const proto1 = new Prototype(divPrototypeConfig);
|
||||||
|
const protoConfig2 = cloneDeep(divPrototypeConfig);
|
||||||
|
set(protoConfig2, 'componentName', 'Div2');
|
||||||
|
const proto2 = new Prototype(protoConfig2);
|
||||||
|
|
||||||
|
const protoConfig3 = cloneDeep(divPrototypeConfig);
|
||||||
|
set(protoConfig3, 'componentName', 'Div3');
|
||||||
|
const proto3 = new Prototype(protoConfig3);
|
||||||
|
|
||||||
|
const mockComponentPrototype = jest.fn();
|
||||||
|
jest.mock('../../src/bundle/bundle', () => {
|
||||||
|
// return {
|
||||||
|
// mockComponentPrototype: jest.fn().mockImplementation(() => {
|
||||||
|
// return proto;
|
||||||
|
// }),
|
||||||
|
// }
|
||||||
|
// return jest.fn().mockImplementation(() => {
|
||||||
|
// return {playSoundFile: fakePlaySoundFile};
|
||||||
|
// });
|
||||||
|
return jest.fn().mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
get: () => {},
|
||||||
|
getList: () => { return []; },
|
||||||
|
getFromMeta: () => {},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockError = jest.fn();
|
||||||
|
jest.mock('@ali/vu-logger');
|
||||||
|
lg.error = mockError;
|
||||||
|
|
||||||
|
function wrap(name, thing) {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
componentName: name,
|
||||||
|
category: '布局',
|
||||||
|
module: thing,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getComponentProtos() {
|
||||||
|
return [
|
||||||
|
wrap('Div', proto1),
|
||||||
|
// wrap('Div2', proto2),
|
||||||
|
// wrap('Div3', proto3),
|
||||||
|
wrap('DivPortal', [proto2, proto3]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Div extends Component {}
|
||||||
|
Div.displayName = 'Div';
|
||||||
|
class Div2 extends Component {}
|
||||||
|
Div2.displayName = 'Div2';
|
||||||
|
class Div3 extends Component {}
|
||||||
|
Div3.displayName = 'Div3';
|
||||||
|
|
||||||
|
function getComponentViews() {
|
||||||
|
return [
|
||||||
|
wrap('Div', Div),
|
||||||
|
// wrap('Div2', Div2),
|
||||||
|
// wrap('Div3', Div3),
|
||||||
|
wrap('DivPortal', [Div2, Div3]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Trunk', () => {
|
||||||
|
it('构造函数', () => {
|
||||||
|
const warn = console.warn = jest.fn();
|
||||||
|
const trunkChangeHandler = jest.fn();
|
||||||
|
const off = trunk.onTrunkChange(trunkChangeHandler);
|
||||||
|
trunk.addBundle(new Bundle([proto1], [Div]));
|
||||||
|
trunk.addBundle(new Bundle([proto2], [Div2]));
|
||||||
|
expect(trunkChangeHandler).toHaveBeenCalledTimes(2);
|
||||||
|
off();
|
||||||
|
trunk.addBundle(new Bundle([proto3], [Div3]));
|
||||||
|
expect(trunkChangeHandler).toHaveBeenCalledTimes(2);
|
||||||
|
trunk.getList();
|
||||||
|
trunk.getPrototype('Div');
|
||||||
|
trunk.getPrototypeById('Div');
|
||||||
|
trunk.getPrototypeView('Div');
|
||||||
|
trunk.listByCategory();
|
||||||
|
expect(trunk.mockComponentPrototype(new Bundle([proto3], [Div3]))).toBeUndefined;
|
||||||
|
expect(mockError).toHaveBeenCalled();
|
||||||
|
trunk.registerComponentPrototypeMocker({ mockPrototype: jest.fn().mockImplementation(() => { return proto3; }) });
|
||||||
|
expect(trunk.mockComponentPrototype(new Bundle([proto3], [Div3]))).toBe(proto3);
|
||||||
|
const hahaSetter = () => 'haha';
|
||||||
|
trunk.registerSetter('haha', hahaSetter);
|
||||||
|
expect(trunk.getSetter('haha')).toBe(hahaSetter);
|
||||||
|
trunk.getRecents(5);
|
||||||
|
trunk.setPackages();
|
||||||
|
expect(warn).toHaveBeenCalledTimes(1);
|
||||||
|
trunk.beforeLoadBundle();
|
||||||
|
expect(warn).toHaveBeenCalledTimes(2);
|
||||||
|
trunk.afterLoadBundle();
|
||||||
|
expect(warn).toHaveBeenCalledTimes(3);
|
||||||
|
trunk.getBundle();
|
||||||
|
expect(warn).toHaveBeenCalledTimes(4);
|
||||||
|
expect(trunk.isReady()).toBeTruthy;
|
||||||
|
});
|
||||||
|
});
|
||||||
293
packages/editor-preset-vision/tests/fixtures/prototype/div-vision-full.ts
vendored
Normal file
293
packages/editor-preset-vision/tests/fixtures/prototype/div-vision-full.ts
vendored
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
export default {
|
||||||
|
title: '容器',
|
||||||
|
componentName: 'Div',
|
||||||
|
docUrl: 'http://gitlab.alibaba-inc.com/vision-components/vc-block/blob/master/README.md',
|
||||||
|
category: '布局',
|
||||||
|
isContainer: true,
|
||||||
|
canOperating: false,
|
||||||
|
extraActions: [],
|
||||||
|
canContain: 'Form',
|
||||||
|
canDropTo: 'Div',
|
||||||
|
canDropIn: 'Div',
|
||||||
|
canResizing: true,
|
||||||
|
canDraging: false,
|
||||||
|
context: {},
|
||||||
|
initialChildren() {},
|
||||||
|
didDropIn() {},
|
||||||
|
didDropOut() {},
|
||||||
|
subtreeModified() {},
|
||||||
|
onResize() {},
|
||||||
|
onResizeStart() {},
|
||||||
|
onResizeEnd() {},
|
||||||
|
canUseCondition: true,
|
||||||
|
canLoop: true,
|
||||||
|
snippets: [
|
||||||
|
{
|
||||||
|
screenshot: 'https://img.alicdn.com/tfs/TB1CHN3u4z1gK0jSZSgXXavwpXa-112-64.png',
|
||||||
|
label: '普通型',
|
||||||
|
schema: {
|
||||||
|
componentName: 'Div',
|
||||||
|
props: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
configure: [
|
||||||
|
{
|
||||||
|
name: 'myName',
|
||||||
|
title: '我的名字',
|
||||||
|
display: 'tab',
|
||||||
|
initialValue: 'NORMAL',
|
||||||
|
defaultValue: 'NORMAL',
|
||||||
|
collapsed: true,
|
||||||
|
supportVariable: true,
|
||||||
|
accessor(field, val) {},
|
||||||
|
mutator(field, val) {},
|
||||||
|
disabled() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
useVariableChange() {},
|
||||||
|
allowTextInput: true,
|
||||||
|
liveTextEditing: true,
|
||||||
|
setter: [
|
||||||
|
{
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
title: '普通',
|
||||||
|
value: 'NORMAL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '隐藏',
|
||||||
|
value: 'HIDDEN',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
loose: false,
|
||||||
|
cancelable: false,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
title: '普通',
|
||||||
|
value: 'NORMAL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '隐藏',
|
||||||
|
value: 'HIDDEN',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
loose: false,
|
||||||
|
cancelable: false,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mySlotName',
|
||||||
|
slotName: 'mySlotName',
|
||||||
|
slotTitle: '我的 Slot 名字',
|
||||||
|
display: 'tab',
|
||||||
|
initialValue: 'NORMAL',
|
||||||
|
defaultValue: 'NORMAL',
|
||||||
|
collapsed: true,
|
||||||
|
supportVariable: true,
|
||||||
|
accessor(field, val) {},
|
||||||
|
mutator(field, val) {},
|
||||||
|
disabled() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
title: '普通',
|
||||||
|
value: 'NORMAL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '隐藏',
|
||||||
|
value: 'HIDDEN',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
loose: false,
|
||||||
|
cancelable: false,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'behavior',
|
||||||
|
title: '默认状态',
|
||||||
|
display: 'inline',
|
||||||
|
initialValue: 'NORMAL',
|
||||||
|
supportVariable: true,
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
title: '普通',
|
||||||
|
value: 'NORMAL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '隐藏',
|
||||||
|
value: 'HIDDEN',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
loose: false,
|
||||||
|
cancelable: false,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '__style__',
|
||||||
|
title: '样式设置',
|
||||||
|
display: 'accordion',
|
||||||
|
collapsed: false,
|
||||||
|
initialValue: {},
|
||||||
|
tip: {
|
||||||
|
url: 'https://lark.alipay.com/legao/help/design-tool-style',
|
||||||
|
content: '点击 ? 查看样式设置器用法指南',
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
advanced: true,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
title: '高级',
|
||||||
|
display: 'accordion',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: 'fieldId',
|
||||||
|
title: '唯一标识',
|
||||||
|
display: 'block',
|
||||||
|
tip:
|
||||||
|
'组件的唯一标识符,不能够与其它组件重名,不能够为空,且只能够使用以字母开头的,下划线以及数字的组合。',
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
placeholder: '请输入唯一标识',
|
||||||
|
multiline: false,
|
||||||
|
rows: 10,
|
||||||
|
required: false,
|
||||||
|
pattern: null,
|
||||||
|
maxLength: null,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'useFieldIdAsDomId',
|
||||||
|
title: '将唯一标识用作 DOM ID',
|
||||||
|
display: 'block',
|
||||||
|
tip:
|
||||||
|
'开启这个配置项后,会在当前组件的 HTML 元素上加入 id="当前组件的 fieldId",一般用于做 utils 的绑定,不常用',
|
||||||
|
initialValue: false,
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'customClassName',
|
||||||
|
title: '自定义样式类',
|
||||||
|
display: 'block',
|
||||||
|
supportVariable: true,
|
||||||
|
initialValue: '',
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
placeholder: null,
|
||||||
|
multiline: false,
|
||||||
|
rows: 10,
|
||||||
|
required: false,
|
||||||
|
pattern: null,
|
||||||
|
maxLength: null,
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'events',
|
||||||
|
title: '动作设置',
|
||||||
|
tip: {
|
||||||
|
url: 'https://lark.alipay.com/legao/legao/events-call',
|
||||||
|
content: '点击 ? 查看如何设置组件的事件响应动作',
|
||||||
|
},
|
||||||
|
display: 'accordion',
|
||||||
|
initialValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
key: null,
|
||||||
|
ref: null,
|
||||||
|
props: {
|
||||||
|
events: [
|
||||||
|
{
|
||||||
|
name: 'onClick',
|
||||||
|
title: '当点击时',
|
||||||
|
initialValue:
|
||||||
|
"/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseEnter',
|
||||||
|
title: '当鼠标进入时',
|
||||||
|
initialValue:
|
||||||
|
"/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseLeave',
|
||||||
|
title: '当鼠标离开时',
|
||||||
|
initialValue:
|
||||||
|
"/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
_owner: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onClick',
|
||||||
|
display: 'none',
|
||||||
|
initialValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseEnter',
|
||||||
|
display: 'none',
|
||||||
|
initialValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'onMouseLeave',
|
||||||
|
display: 'none',
|
||||||
|
initialValue: {
|
||||||
|
ignored: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@ -89,7 +89,7 @@ export default {
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
componentName: 'Form',
|
componentName: 'Form',
|
||||||
id: 'node_k1ow3cbq',
|
id: 'form',
|
||||||
props: {
|
props: {
|
||||||
size: 'medium',
|
size: 'medium',
|
||||||
labelAlign: 'top',
|
labelAlign: 'top',
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
import set from 'lodash/set';
|
||||||
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
|
import '../fixtures/window';
|
||||||
|
import formSchema from '../fixtures/schema/form';
|
||||||
|
import VisualEngine from '../../src';
|
||||||
|
|
||||||
|
describe('VisualEngine.Exchange 相关 API 测试', () => {
|
||||||
|
it('select / getSelected', () => {
|
||||||
|
const doc = VisualEngine.Pages.addPage(formSchema);
|
||||||
|
VisualEngine.Exchange.select(doc?.getNode('form'));
|
||||||
|
expect(VisualEngine.Exchange.getSelected()?.componentName).toBe('Form');
|
||||||
|
expect(VisualEngine.Exchange.getSelected()?.id).toBe('form');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('onIntoView', () => {
|
||||||
|
expect(typeof VisualEngine.Exchange.onIntoView).toBe('function');
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -2,9 +2,10 @@ import set from 'lodash/set';
|
|||||||
import cloneDeep from 'lodash/clonedeep';
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
import '../fixtures/window';
|
import '../fixtures/window';
|
||||||
import formSchema from '../fixtures/schema/form';
|
import formSchema from '../fixtures/schema/form';
|
||||||
import VisualEngine from '../../src';
|
import VisualEngine, { Prototype } from '../../src';
|
||||||
import { Editor } from '@ali/lowcode-editor-core';
|
import { Editor } from '@ali/lowcode-editor-core';
|
||||||
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
||||||
|
import divPrototypeConfig from '../fixtures/prototype/div-vision';
|
||||||
|
|
||||||
const pageSchema = { componentsTree: [formSchema] };
|
const pageSchema = { componentsTree: [formSchema] };
|
||||||
|
|
||||||
@ -62,6 +63,14 @@ describe('VisualEngine.Pages 相关 API 测试', () => {
|
|||||||
// slot 会多出(1 + N)个节点
|
// slot 会多出(1 + N)个节点
|
||||||
expect(doc.nodesMap.size).toBe(expectedNodeCnt + 2);
|
expect(doc.nodesMap.size).toBe(expectedNodeCnt + 2);
|
||||||
});
|
});
|
||||||
|
it.only('基本的节点模型初始化,初始化传入 schema,构造 prototype', () => {
|
||||||
|
const proto = new Prototype(divPrototypeConfig);
|
||||||
|
const doc = VisualEngine.Pages.addPage(pageSchema)!;
|
||||||
|
expect(doc).toBeTruthy();
|
||||||
|
const ids = getIdsFromSchema(formSchema);
|
||||||
|
const expectedNodeCnt = ids.length;
|
||||||
|
expect(doc.nodesMap.size).toBe(expectedNodeCnt);
|
||||||
|
});
|
||||||
it('导出 schema', () => {
|
it('导出 schema', () => {
|
||||||
const doc = VisualEngine.Pages.addPage(pageSchema)!;
|
const doc = VisualEngine.Pages.addPage(pageSchema)!;
|
||||||
expect(doc).toBeTruthy();
|
expect(doc).toBeTruthy();
|
||||||
|
|||||||
@ -1,38 +1,26 @@
|
|||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import cloneDeep from 'lodash/clonedeep';
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
import '../fixtures/window';
|
import '../fixtures/window';
|
||||||
// import { Project } from '../../src/project/project';
|
|
||||||
// import { Node } from '../../src/document/node/node';
|
|
||||||
// import { Designer } from '../../src/designer/designer';
|
|
||||||
import formSchema from '../fixtures/schema/form';
|
import formSchema from '../fixtures/schema/form';
|
||||||
import VisualEngine from '../../src';
|
import { Project } from '../../src';
|
||||||
import { Editor } from '@ali/lowcode-editor-core';
|
|
||||||
|
|
||||||
// import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
|
||||||
|
|
||||||
|
|
||||||
describe.skip('VisualEngine.Project 相关 API 测试', () => {
|
describe.skip('VisualEngine.Project 相关 API 测试', () => {
|
||||||
describe('getSchema / setSchema 系列', () => {
|
it('getSchema / setSchema 系列', () => {
|
||||||
it('基本的节点模型初始化,模型导出,初始化传入 schema', () => {
|
Project.setSchema({
|
||||||
// console.log(VisualEngine);
|
componentsMap: {},
|
||||||
// console.log(Editor instanceof Function);
|
componentsTree: [formSchema],
|
||||||
// console.log(Editor.toString())
|
|
||||||
// console.log(new Editor());
|
|
||||||
// console.log(Editor2 instanceof Function);
|
|
||||||
|
|
||||||
console.log(VisualEngine.Pages.addPage(formSchema));
|
|
||||||
});
|
});
|
||||||
|
expect(Project.getSchema()).toEqual({
|
||||||
|
componentsMap: {},
|
||||||
|
componentsTree: [formSchema],
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setConfig 系列', () => {
|
it('setConfig', () => {
|
||||||
it('基本的节点模型初始化,模型导出,初始化传入 schema', () => {
|
Project.setConfig({ haha: 1 });
|
||||||
// console.log(VisualEngine);
|
expect(Project.get('config')).toEqual({
|
||||||
// console.log(Editor instanceof Function);
|
haha: 1,
|
||||||
// console.log(Editor.toString())
|
|
||||||
// console.log(new Editor());
|
|
||||||
// console.log(Editor2 instanceof Function);
|
|
||||||
|
|
||||||
console.log(VisualEngine.Pages.addPage(formSchema));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,5 +12,6 @@ module.exports = {
|
|||||||
'no-prototype-builtins': 1,
|
'no-prototype-builtins': 1,
|
||||||
'no-confusing-arrow': 1,
|
'no-confusing-arrow': 1,
|
||||||
'no-case-declarations': 1,
|
'no-case-declarations': 1,
|
||||||
|
'lines-between-class-members': 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,7 +11,7 @@ import { createIcon } from '@ali/lowcode-utils';
|
|||||||
@observer
|
@observer
|
||||||
export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any }, { shouldIgnoreRoot: boolean }> {
|
export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any }, { shouldIgnoreRoot: boolean }> {
|
||||||
state = {
|
state = {
|
||||||
shouldIgnoreRoot: false,
|
shouldIgnoreRoot: false,
|
||||||
};
|
};
|
||||||
private main = new SettingsMain(this.props.editor);
|
private main = new SettingsMain(this.props.editor);
|
||||||
|
|
||||||
@ -24,12 +24,12 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setShouldIgnoreRoot();
|
this.setShouldIgnoreRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
async setShouldIgnoreRoot() {
|
async setShouldIgnoreRoot() {
|
||||||
let designMode = await this.props.editor.get('designMode');
|
const designMode = await this.props.editor.get('designMode');
|
||||||
this.setState({
|
this.setState({
|
||||||
shouldIgnoreRoot: designMode === 'live',
|
shouldIgnoreRoot: designMode === 'live',
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user