mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-20 07:14:23 +00:00
chore(test): 增加 hotkey / host 部分单测
This commit is contained in:
parent
077b904171
commit
22aa77610a
@ -3,7 +3,7 @@ module.exports = {
|
|||||||
ignorePatterns: [ 'tests/* '],
|
ignorePatterns: [ 'tests/* '],
|
||||||
rules: {
|
rules: {
|
||||||
'react/no-multi-comp': 0,
|
'react/no-multi-comp': 0,
|
||||||
'no-unused-expressions': 1,
|
'no-unused-expressions': 0,
|
||||||
'implicit-arrow-linebreak': 1,
|
'implicit-arrow-linebreak': 1,
|
||||||
'no-nested-ternary': 1,
|
'no-nested-ternary': 1,
|
||||||
'no-mixed-operators': 1,
|
'no-mixed-operators': 1,
|
||||||
|
|||||||
@ -11,6 +11,7 @@ module.exports = {
|
|||||||
transformIgnorePatterns: [
|
transformIgnorePatterns: [
|
||||||
`/node_modules/(?!${esModules})/`,
|
`/node_modules/(?!${esModules})/`,
|
||||||
],
|
],
|
||||||
|
setupFiles: ['./tests/fixtures/unhandled-rejection.ts'],
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
||||||
collectCoverage: false,
|
collectCoverage: false,
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ali/lowcode-test-mate": "^1.0.1",
|
"@ali/lowcode-test-mate": "^1.0.1",
|
||||||
"@alib/build-scripts": "^0.1.18",
|
"@alib/build-scripts": "^0.1.29",
|
||||||
"@types/classnames": "^2.2.7",
|
"@types/classnames": "^2.2.7",
|
||||||
"@types/medium-editor": "^5.0.3",
|
"@types/medium-editor": "^5.0.3",
|
||||||
"@types/node": "^13.7.1",
|
"@types/node": "^13.7.1",
|
||||||
|
|||||||
@ -473,12 +473,12 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.disableDetecting = () => {
|
// this.disableDetecting = () => {
|
||||||
detecting.leave(this.project.currentDocument);
|
// detecting.leave(this.project.currentDocument);
|
||||||
doc.removeEventListener('mouseover', hover, true);
|
// doc.removeEventListener('mouseover', hover, true);
|
||||||
doc.removeEventListener('mouseleave', leave, false);
|
// doc.removeEventListener('mouseleave', leave, false);
|
||||||
this.disableDetecting = undefined;
|
// this.disableDetecting = undefined;
|
||||||
};
|
// };
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly liveEditing = new LiveEditing();
|
readonly liveEditing = new LiveEditing();
|
||||||
@ -525,21 +525,22 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
* @see ISimulator
|
* @see ISimulator
|
||||||
*/
|
*/
|
||||||
setSuspense(suspended: boolean) {
|
setSuspense(suspended: boolean) {
|
||||||
if (suspended) {
|
return false;
|
||||||
/*
|
// if (suspended) {
|
||||||
if (this.disableDetecting) {
|
// /*
|
||||||
this.disableDetecting();
|
// if (this.disableDetecting) {
|
||||||
}
|
// this.disableDetecting();
|
||||||
*/
|
// }
|
||||||
// sleep some autorun reaction
|
// */
|
||||||
} else {
|
// // sleep some autorun reaction
|
||||||
// weekup some autorun reaction
|
// } else {
|
||||||
/*
|
// // weekup some autorun reaction
|
||||||
if (!this.disableDetecting) {
|
// /*
|
||||||
this.setupDetecting();
|
// if (!this.disableDetecting) {
|
||||||
}
|
// this.setupDetecting();
|
||||||
*/
|
// }
|
||||||
}
|
// */
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
setupContextMenu() {
|
setupContextMenu() {
|
||||||
|
|||||||
@ -247,8 +247,9 @@ export class Prop implements IPropParent {
|
|||||||
value: valueToSource(val),
|
value: valueToSource(val),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const editor = globalContext.get(Editor);
|
if (globalContext.has(Editor)) {
|
||||||
editor.emit('node.prop.change', { prop: this, node: this.owner });
|
globalContext.get(Editor).emit('node.prop.change', { prop: this, node: this.owner });
|
||||||
|
}
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { Editor } from '@ali/lowcode-editor-core';
|
|||||||
import { Project } from '../../src/project/project';
|
import { Project } from '../../src/project/project';
|
||||||
import { Node } from '../../src/document/node/node';
|
import { Node } from '../../src/document/node/node';
|
||||||
import TestRenderer from 'react-test-renderer';
|
import TestRenderer from 'react-test-renderer';
|
||||||
import { configure, render } from 'enzyme';
|
import { configure, render, mount } from 'enzyme';
|
||||||
import Adapter from 'enzyme-adapter-react-16';
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
import { Designer } from '../../src/designer/designer';
|
import { Designer } from '../../src/designer/designer';
|
||||||
import formSchema from '../fixtures/schema/form';
|
import formSchema from '../fixtures/schema/form';
|
||||||
@ -16,7 +16,7 @@ import { BuiltinSimulatorHostView } from '../../src/builtin-simulator/host-view'
|
|||||||
configure({ adapter: new Adapter() });
|
configure({ adapter: new Adapter() });
|
||||||
const editor = new Editor();
|
const editor = new Editor();
|
||||||
|
|
||||||
describe('setting-prop-entry 测试', () => {
|
describe('host-view 测试', () => {
|
||||||
let designer: Designer;
|
let designer: Designer;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
designer = new Designer({ editor });
|
designer = new Designer({ editor });
|
||||||
@ -26,9 +26,7 @@ describe('setting-prop-entry 测试', () => {
|
|||||||
designer = null;
|
designer = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('xxx', () => {
|
it('host-view', () => {
|
||||||
// console.log(JSON.stringify(TestRenderer.create(<BuiltinSimulatorHostView project={designer.project} />).toJSON()));
|
const hostView = render(<BuiltinSimulatorHostView project={designer.project} />);
|
||||||
|
|
||||||
console.log(render(<BuiltinSimulatorHostView project={designer.project} ref={(xxx) => { console.log('xxx', xxx)}}/>))
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,17 +3,25 @@ import set from 'lodash/set';
|
|||||||
import cloneDeep from 'lodash/clonedeep';
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
import '../fixtures/window';
|
import '../fixtures/window';
|
||||||
import { Editor } from '@ali/lowcode-editor-core';
|
import { Editor } from '@ali/lowcode-editor-core';
|
||||||
|
import {
|
||||||
|
AssetLevel,
|
||||||
|
Asset,
|
||||||
|
AssetList,
|
||||||
|
assetBundle,
|
||||||
|
assetItem,
|
||||||
|
AssetType,
|
||||||
|
} from '@ali/lowcode-utils';
|
||||||
import { Project } from '../../src/project/project';
|
import { Project } from '../../src/project/project';
|
||||||
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 formSchema from '../fixtures/schema/form';
|
import formSchema from '../fixtures/schema/form';
|
||||||
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
import { getMockDocument, getMockWindow, getMockEvent } from '../utils';
|
||||||
import { BuiltinSimulatorHost } from '../../src/builtin-simulator/host';
|
import { BuiltinSimulatorHost } from '../../src/builtin-simulator/host';
|
||||||
|
import { eq } from 'lodash';
|
||||||
|
|
||||||
const editor = new Editor();
|
const editor = new Editor();
|
||||||
|
|
||||||
describe('setting-prop-entry 测试', () => {
|
describe('host 测试', () => {
|
||||||
let designer: Designer;
|
let designer: Designer;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
designer = new Designer({ editor });
|
designer = new Designer({ editor });
|
||||||
@ -23,7 +31,115 @@ describe('setting-prop-entry 测试', () => {
|
|||||||
designer = null;
|
designer = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dummy test', () => {
|
it('基础方法测试', async () => {
|
||||||
console.log(new BuiltinSimulatorHost(designer.project));
|
const host = new BuiltinSimulatorHost(designer.project);
|
||||||
|
expect(host.currentDocument).toBe(designer.project.currentDocument);
|
||||||
|
expect(host.renderEnv).toBe('default');
|
||||||
|
expect(host.device).toBe('default');
|
||||||
|
expect(host.deviceClassName).toBeUndefined;
|
||||||
|
host.setProps({
|
||||||
|
renderEnv: 'rax',
|
||||||
|
device: 'mobile',
|
||||||
|
deviceClassName: 'mobile-rocks',
|
||||||
|
componentsAsset: [{
|
||||||
|
type: AssetType.JSText,
|
||||||
|
content: 'console.log(1)',
|
||||||
|
}, {
|
||||||
|
type: AssetType.JSUrl,
|
||||||
|
content: '//path/to/js',
|
||||||
|
}],
|
||||||
|
theme: {
|
||||||
|
type: AssetType.CSSText,
|
||||||
|
content: '.theme {font-size: 50px;}',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(host.renderEnv).toBe('rax');
|
||||||
|
expect(host.device).toBe('mobile');
|
||||||
|
expect(host.deviceClassName).toBe('mobile-rocks');
|
||||||
|
expect(host.componentsAsset).toEqual([{
|
||||||
|
type: AssetType.JSText,
|
||||||
|
content: 'console.log(1)',
|
||||||
|
}, {
|
||||||
|
type: AssetType.JSUrl,
|
||||||
|
content: '//path/to/js',
|
||||||
|
}]);
|
||||||
|
expect(host.theme).toEqual({
|
||||||
|
type: AssetType.CSSText,
|
||||||
|
content: '.theme {font-size: 50px;}',
|
||||||
|
});
|
||||||
|
expect(host.componentsMap).toBe(designer.componentsMap);
|
||||||
|
|
||||||
|
host.set('renderEnv', 'vue');
|
||||||
|
expect(host.renderEnv).toBe('vue');
|
||||||
|
|
||||||
|
expect(host.getComponentContext).toThrow('Method not implemented.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('事件测试', async () => {
|
||||||
|
const host = new BuiltinSimulatorHost(designer.project);
|
||||||
|
const mockDocument = getMockDocument();
|
||||||
|
const mockWindow = getMockWindow(mockDocument);
|
||||||
|
const mockIframe = {
|
||||||
|
contentWindow: mockWindow,
|
||||||
|
contentDocument: mockDocument,
|
||||||
|
dispatchEvent() {},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 非法分支测试
|
||||||
|
host.mountContentFrame();
|
||||||
|
expect(host._iframe).toBeUndefined();
|
||||||
|
|
||||||
|
host.set('library', [{
|
||||||
|
package: '@ali/vc-deep',
|
||||||
|
library: 'lib',
|
||||||
|
urls: ['a.js', 'b.js']
|
||||||
|
}]);
|
||||||
|
|
||||||
|
host.componentsConsumer.consume(() => {});
|
||||||
|
host.injectionConsumer.consume(() => {});
|
||||||
|
await host.mountContentFrame(mockIframe);
|
||||||
|
|
||||||
|
expect(host.contentWindow).toBe(mockWindow);
|
||||||
|
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'mouseover',
|
||||||
|
getMockEvent(mockDocument.createElement('div')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'mouseleave',
|
||||||
|
getMockEvent(mockDocument.createElement('div')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'mousedown',
|
||||||
|
getMockEvent(mockDocument.createElement('div')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'mouseup',
|
||||||
|
getMockEvent(mockDocument.createElement('div')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'mousemove',
|
||||||
|
getMockEvent(mockDocument.createElement('div')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'click',
|
||||||
|
getMockEvent(document.createElement('input')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'dblclick',
|
||||||
|
getMockEvent(mockDocument.createElement('div')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
|
mockDocument.triggerEventListener(
|
||||||
|
'contextmenu',
|
||||||
|
getMockEvent(mockDocument.createElement('div')),
|
||||||
|
host,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { parseMetadata } from '../../src/builtin-simulator/utils/parse-metadata'
|
|||||||
|
|
||||||
describe('parseMetadata', () => {
|
describe('parseMetadata', () => {
|
||||||
it('parseMetadata', async () => {
|
it('parseMetadata', async () => {
|
||||||
console.log(parseMetadata('Div'))
|
const md1 = parseMetadata('Div');
|
||||||
console.log(parseMetadata({ componentName: 'Div' }));
|
const md2 = parseMetadata({ componentName: 'Div' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
21
packages/designer/tests/builtin-simulator/renderer.test.tsx
Normal file
21
packages/designer/tests/builtin-simulator/renderer.test.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react';
|
||||||
|
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 TestRenderer from 'react-test-renderer';
|
||||||
|
import { configure, render, mount } from 'enzyme';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { Designer } from '../../src/designer/designer';
|
||||||
|
import formSchema from '../fixtures/schema/form';
|
||||||
|
import { getMockRenderer } from '../utils';
|
||||||
|
import { isSimulatorRenderer } from '../../src/builtin-simulator/renderer';
|
||||||
|
|
||||||
|
|
||||||
|
describe('renderer 测试', () => {
|
||||||
|
it('renderer', () => {
|
||||||
|
expect(isSimulatorRenderer(getMockRenderer())).toBeTruthy;
|
||||||
|
})
|
||||||
|
});
|
||||||
202
packages/designer/tests/designer/builtin-hotkey.test.ts
Normal file
202
packages/designer/tests/designer/builtin-hotkey.test.ts
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
import set from 'lodash/set';
|
||||||
|
import cloneDeep from 'lodash/clonedeep';
|
||||||
|
import '../fixtures/window';
|
||||||
|
import { Editor, globalContext } from '@ali/lowcode-editor-core';
|
||||||
|
import { Designer } from '../../src/designer/designer';
|
||||||
|
import { Project } from '../../src/project/project';
|
||||||
|
import formSchema from '../fixtures/schema/form';
|
||||||
|
import '../../src/designer/builtin-hotkey';
|
||||||
|
|
||||||
|
const editor = new Editor();
|
||||||
|
|
||||||
|
let designer: Designer;
|
||||||
|
beforeAll(() => {
|
||||||
|
globalContext.register(editor, Editor);
|
||||||
|
});
|
||||||
|
beforeEach(() => {
|
||||||
|
designer = new Designer({ editor });
|
||||||
|
designer.project.open(formSchema);
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
designer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// keyCode 对应表:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
|
||||||
|
// hotkey 模块底层用的 keyCode,所以还不能用 key / code 测试
|
||||||
|
describe('快捷键测试', () => {
|
||||||
|
it('right', () => {
|
||||||
|
const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbj')!;
|
||||||
|
firstCardNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 39 });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(designer.currentSelection?.selected.includes('node_k1ow3cbl')).toBeTruthy;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('left', () => {
|
||||||
|
const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbl')!;
|
||||||
|
firstCardNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 37 });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(designer.currentSelection?.selected.includes('node_k1ow3cbj')).toBeTruthy;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('down', () => {
|
||||||
|
const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbl')!;
|
||||||
|
firstCardNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 40 });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(designer.currentSelection?.selected.includes('node_k1ow3cbm')).toBeTruthy;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('up', () => {
|
||||||
|
const secondCardNode = designer.currentDocument?.getNode('node_k1ow3cbm')!;
|
||||||
|
secondCardNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 38 });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(designer.currentSelection?.selected.includes('node_k1ow3cbl')).toBeTruthy;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 跟右侧节点调换位置
|
||||||
|
it('option + right', () => {
|
||||||
|
const firstButtonNode = designer.currentDocument?.getNode('node_k1ow3cbn')!;
|
||||||
|
firstButtonNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 39, altKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(firstButtonNode.prevSibling?.getId()).toBe('node_k1ow3cbp');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 跟左侧节点调换位置
|
||||||
|
it('option + left', () => {
|
||||||
|
const secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
secondButtonNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 37, altKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(secondButtonNode.nextSibling?.getId()).toBe('node_k1ow3cbn');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 向父级移动该节点
|
||||||
|
it('option + up', () => {
|
||||||
|
const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
firstCardNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 38, altKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将节点移入到兄弟节点中
|
||||||
|
it('option + up', () => {
|
||||||
|
const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
firstCardNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 40, altKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 撤销
|
||||||
|
it('command + z', async () => {
|
||||||
|
const firstButtonNode = designer.currentDocument?.getNode('node_k1ow3cbn')!;
|
||||||
|
let secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
|
||||||
|
firstButtonNode.remove();
|
||||||
|
expect(secondButtonNode.getParent()?.children.size).toBe(1);
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 90, metaKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
// 重新获取一次节点,因为 documentModel.import 是全画布刷新
|
||||||
|
secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
expect(secondButtonNode.getParent()?.children.size).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重做
|
||||||
|
it('command + y', async () => {
|
||||||
|
const firstButtonNode = designer.currentDocument?.getNode('node_k1ow3cbn')!;
|
||||||
|
let secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
|
||||||
|
firstButtonNode.remove();
|
||||||
|
expect(secondButtonNode.getParent()?.children.size).toBe(1);
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 90, metaKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
// 重新获取一次节点,因为 documentModel.import 是全画布刷新
|
||||||
|
secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
expect(secondButtonNode.getParent()?.children.size).toBe(2);
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
|
event = new KeyboardEvent('keydown', { keyCode: 89, metaKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
// 重新获取一次节点,因为 documentModel.import 是全画布刷新
|
||||||
|
secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
expect(secondButtonNode.getParent()?.children.size).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('command + c', () => {
|
||||||
|
const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
firstCardNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 67, metaKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('command + v', async () => {
|
||||||
|
const secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
secondButtonNode.select();
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 67, metaKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
event = new KeyboardEvent('keydown', { keyCode: 86, metaKey: true });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
|
// clipboard 异步,先注释
|
||||||
|
// expect(secondButtonNode.getParent()?.children.size).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 撤销所有选中
|
||||||
|
it('escape', () => {
|
||||||
|
const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
firstCardNode.select();
|
||||||
|
|
||||||
|
expect(designer.currentSelection!.selected.includes('node_k1ow3cbp')).toBeTruthy;
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 27 });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(designer.currentSelection!.selected.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 删除节点
|
||||||
|
it('delete', () => {
|
||||||
|
const firstButtonNode = designer.currentDocument?.getNode('node_k1ow3cbn')!;
|
||||||
|
const secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||||
|
firstButtonNode.select();
|
||||||
|
|
||||||
|
expect(secondButtonNode.prevSibling.id).toBe('node_k1ow3cbn');
|
||||||
|
|
||||||
|
let event = new KeyboardEvent('keydown', { keyCode: 46 });
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
expect(secondButtonNode.prevSibling).toBeNull;
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,14 +1,14 @@
|
|||||||
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 { Editor } from '@ali/lowcode-editor-core';
|
import { Editor } from '@ali/lowcode-editor-core';
|
||||||
import { Project } from '../../src/project/project';
|
import { Project } from '../../../src/project/project';
|
||||||
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 formSchema from '../fixtures/schema/form';
|
import formSchema from '../../../fixtures/schema/form';
|
||||||
import settingSchema from '../fixtures/schema/setting';
|
import settingSchema from '../../fixtures/schema/setting';
|
||||||
import divMeta from '../fixtures/prototype/div-meta';
|
import divMeta from '../../fixtures/prototype/div-meta';
|
||||||
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
import { getIdsFromSchema, getNodeFromSchemaById } from '../../utils';
|
||||||
|
|
||||||
const editor = new Editor();
|
const editor = new Editor();
|
||||||
|
|
||||||
@ -1,14 +1,14 @@
|
|||||||
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 { Editor } from '@ali/lowcode-editor-core';
|
import { Editor } from '@ali/lowcode-editor-core';
|
||||||
import { Project } from '../../src/project/project';
|
import { Project } from '../../../src/project/project';
|
||||||
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 formSchema from '../fixtures/schema/form';
|
import formSchema from '../../fixtures/schema/form';
|
||||||
import settingSchema from '../fixtures/schema/setting';
|
import settingSchema from '../../fixtures/schema/setting';
|
||||||
import divMeta from '../fixtures/prototype/div-meta';
|
import divMeta from '../../fixtures/prototype/div-meta';
|
||||||
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
import { getIdsFromSchema, getNodeFromSchemaById } from '../../utils';
|
||||||
|
|
||||||
const editor = new Editor();
|
const editor = new Editor();
|
||||||
|
|
||||||
7
packages/designer/tests/fixtures/unhandled-rejection.ts
vendored
Normal file
7
packages/designer/tests/fixtures/unhandled-rejection.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
if (!process.env.LISTENING_TO_UNHANDLED_REJECTION) {
|
||||||
|
process.on('unhandledRejection', reason => {
|
||||||
|
throw reason;
|
||||||
|
})
|
||||||
|
// Avoid memory leak by adding too many listeners
|
||||||
|
process.env.LISTENING_TO_UNHANDLED_REJECTION = true;
|
||||||
|
}
|
||||||
77
packages/designer/tests/utils/bom.ts
Normal file
77
packages/designer/tests/utils/bom.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { getMockRenderer } from './renderer';
|
||||||
|
|
||||||
|
interface MockDocument extends Document {
|
||||||
|
// open(): any;
|
||||||
|
// write(): any;
|
||||||
|
// close(): any;
|
||||||
|
// addEventListener(): any;
|
||||||
|
// removeEventListener(): any;
|
||||||
|
triggerEventListener(): any;
|
||||||
|
// createElement(): any;
|
||||||
|
// appendChild(): any;
|
||||||
|
// removeChild(): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const eventsMap : Map<string, Set<Function>> = new Map<string, Set<Function>>();
|
||||||
|
const mockAddEventListener = jest.fn((eventName: string, cb) => {
|
||||||
|
if (!eventsMap.has(eventName)) {
|
||||||
|
eventsMap.set(eventName, new Set([cb]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eventsMap.get(eventName)!.add(cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockRemoveEventListener = jest.fn((eventName: string, cb) => {
|
||||||
|
if (!eventsMap.has(eventName)) return;
|
||||||
|
if (!cb) {
|
||||||
|
eventsMap.delete(eventName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eventsMap.get(eventName)?.delete(cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockTriggerEventListener = jest.fn((eventName: string, data: any, context: object = {}) => {
|
||||||
|
if (!eventsMap.has(eventName)) return;
|
||||||
|
for (const cb of eventsMap.get(eventName)) {
|
||||||
|
cb.call(context, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockCreateElement = jest.fn((tagName) => {
|
||||||
|
return {
|
||||||
|
style: {},
|
||||||
|
appendChild() {},
|
||||||
|
addEventListener: mockAddEventListener,
|
||||||
|
removeEventListener: mockRemoveEventListener,
|
||||||
|
triggerEventListener: mockTriggerEventListener,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export function getMockDocument(): MockDocument {
|
||||||
|
return {
|
||||||
|
open() {},
|
||||||
|
write() {},
|
||||||
|
close() {},
|
||||||
|
addEventListener: mockAddEventListener,
|
||||||
|
removeEventListener: mockRemoveEventListener,
|
||||||
|
triggerEventListener: mockTriggerEventListener,
|
||||||
|
createElement: mockCreateElement,
|
||||||
|
removeChild() {},
|
||||||
|
body: { appendChild() {}, removeChild() {} },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMockWindow(doc?: MockDocument) {
|
||||||
|
return {
|
||||||
|
SimulatorRenderer: getMockRenderer(),
|
||||||
|
addEventListener: mockAddEventListener,
|
||||||
|
removeEventListener: mockRemoveEventListener,
|
||||||
|
triggerEventListener: mockTriggerEventListener,
|
||||||
|
document: doc || getMockDocument(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearEventsMap() {
|
||||||
|
eventsMap.clear();
|
||||||
|
}
|
||||||
8
packages/designer/tests/utils/event.ts
Normal file
8
packages/designer/tests/utils/event.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export function getMockEvent(target, options) {
|
||||||
|
return {
|
||||||
|
target,
|
||||||
|
preventDefault() {},
|
||||||
|
stopPropagation() {},
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1 +1,4 @@
|
|||||||
export { getIdsFromSchema, getNodeFromSchemaById } from '@ali/lowcode-test-mate/es/utils';
|
export { getIdsFromSchema, getNodeFromSchemaById } from '@ali/lowcode-test-mate/es/utils';
|
||||||
|
export { getMockDocument, getMockWindow } from './bom';
|
||||||
|
export { getMockEvent } from './event';
|
||||||
|
export { getMockRenderer } from './renderer';
|
||||||
8
packages/designer/tests/utils/renderer.ts
Normal file
8
packages/designer/tests/utils/renderer.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export function getMockRenderer() {
|
||||||
|
return {
|
||||||
|
isSimulatorRenderer: true,
|
||||||
|
run() {
|
||||||
|
console.log('renderer run');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@ export function isFormEvent(e: KeyboardEvent | MouseEvent) {
|
|||||||
if (t.form || /^(INPUT|SELECT|TEXTAREA)$/.test(t.tagName)) {
|
if (t.form || /^(INPUT|SELECT|TEXTAREA)$/.test(t.tagName)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (/write/.test(window.getComputedStyle(t).getPropertyValue('-webkit-user-modify'))) {
|
if (t instanceof HTMLElement && /write/.test(window.getComputedStyle(t).getPropertyValue('-webkit-user-modify'))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user