import '../fixtures/window'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { Project } from '../../src/project/project'; import { DocumentModel } from '../../src/document/document-model'; import { Designer } from '../../src/designer/designer'; import { Dragon, isDragNodeObject, isDragNodeDataObject, isDragAnyObject, isLocateEvent, isShaken, setShaken, isInvalidPoint, isSameAs, } from '../../src/designer/dragon'; import { IPublicEnumDragObjectType } from '@alilc/lowcode-types'; import formSchema from '../fixtures/schema/form'; import { fireEvent } from '@testing-library/react'; import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; describe('Dragon 测试', () => { let editor: Editor; let designer: Designer; let project: Project; let doc: DocumentModel; let dragon: Dragon; beforeAll(() => { editor = new Editor(); !globalContext.has(Editor) && globalContext.register(editor, Editor); }); beforeEach(() => { designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = project.createDocument(formSchema); dragon = new Dragon(designer); }); afterEach(() => { project.unload(); project.mountSimulator(undefined); designer.purge(); designer = null; project = null; dragon = null; }); it.skip('drag NodeData', () => { const dragStartMockFn = jest.fn(); const dragMockFn = jest.fn(); const dragEndMockFn = jest.fn(); dragon.onDragstart((e) => { console.log('start', e, e.originalEvent, e.originalEvent.clientX); }); dragon.onDrag((e) => { console.log('drag', e, e.originalEvent, e.originalEvent.clientX); }); dragon.onDragend((e) => { console.log('end', e, e.originalEvent); }); dragon.boost( { type: IPublicEnumDragObjectType.NodeData, data: [{ componentName: 'Button' }], }, new Event('dragstart', { clientX: 100, clientY: 100 }), ); fireEvent.dragOver(document, { clientX: 108, clientY: 108 }); fireEvent.dragEnd(document, { clientX: 118, clientY: 118 }); }); it.skip('drag Node', () => { console.log(new MouseEvent('mousedown', { clientX: 1 }).clientX); // console.log(new Event('mousedown', { clientX: 1 }).clientX); // console.log(new Event('drag', { clientX: 1 }).clientX); // console.log(new CustomEvent('drag', { clientX: 1 }).clientX); console.log(document.createEvent('dragstart', { clientX: 1 }).clientX); }); it('mouse NodeData', () => { const dragStartMockFn = jest.fn(); const dragMockFn = jest.fn(); const dragEndMockFn = jest.fn(); const offDragStart = dragon.onDragstart(dragStartMockFn); const offDrag = dragon.onDrag(dragMockFn); const offDragEnd = dragon.onDragend(dragEndMockFn); dragon.boost( { type: IPublicEnumDragObjectType.NodeData, data: [{ componentName: 'Button' }], }, new MouseEvent('mousedown', { clientX: 100, clientY: 100 }), ); fireEvent.mouseMove(document, { clientX: 108, clientY: 108 }); fireEvent.mouseMove(document, { clientX: 110, clientY: 110 }); fireEvent.mouseUp(document, { clientX: 118, clientY: 118 }); expect(dragStartMockFn).toHaveBeenCalledTimes(1); expect(dragMockFn).toHaveBeenCalledTimes(2); expect(dragEndMockFn).toHaveBeenCalledTimes(1); }); it('mouse Node', () => { const dragStartMockFn = jest.fn(); const dragMockFn = jest.fn(); const dragEndMockFn = jest.fn(); const offDragStart = dragon.onDragstart(dragStartMockFn); const offDrag = dragon.onDrag(dragMockFn); const offDragEnd = dragon.onDragend(dragEndMockFn); dragon.boost( { type: IPublicEnumDragObjectType.Node, nodes: [doc.getNode('node_k1ow3cbn')], }, new MouseEvent('mousedown', { clientX: 100, clientY: 100 }), ); // mouseDown 模式正常不会触发 dragStart 事件,除非 shaken 型 expect(dragStartMockFn).not.toHaveBeenCalled(); fireEvent.mouseMove(document, { clientX: 108, clientY: 108 }); expect(dragStartMockFn).toHaveBeenCalledTimes(1); expect(dragMockFn).toHaveBeenCalledTimes(1); fireEvent.mouseMove(document, { clientX: 110, clientY: 110 }); expect(dragMockFn).toHaveBeenCalledTimes(2); expect(dragon.dragging).toBeTruthy(); fireEvent.mouseUp(document, { clientX: 118, clientY: 118 }); expect(dragEndMockFn).toHaveBeenCalledTimes(1); offDragStart(); offDrag(); offDragEnd(); dragMockFn.mockClear(); dragon.boost( { type: IPublicEnumDragObjectType.Node, nodes: [doc.getNode('node_k1ow3cbn')], }, new MouseEvent('mousedown', { clientX: 100, clientY: 100 }), ); fireEvent.mouseMove(document, { clientX: 108, clientY: 108 }); expect(dragMockFn).not.toHaveBeenCalled(); }); it('mouse Node & esc', () => { const dragStartMockFn = jest.fn(); const dragMockFn = jest.fn(); const dragEndMockFn = jest.fn(); const offDragStart = dragon.onDragstart(dragStartMockFn); const offDrag = dragon.onDrag(dragMockFn); const offDragEnd = dragon.onDragend(dragEndMockFn); dragon.boost( { type: IPublicEnumDragObjectType.Node, nodes: [doc.getNode('node_k1ow3cbn')], }, new MouseEvent('mousedown', { clientX: 100, clientY: 100 }), ); fireEvent.keyDown(document, { keyCode: 27 }); expect(dragon.designer.dropLocation).toBeUndefined(); }); it('mouse Node & copy', () => { const dragStartMockFn = jest.fn(); const dragMockFn = jest.fn(); const dragEndMockFn = jest.fn(); const offDragStart = dragon.onDragstart(dragStartMockFn); const offDrag = dragon.onDrag(dragMockFn); const offDragEnd = dragon.onDragend(dragEndMockFn); dragon.boost( { type: IPublicEnumDragObjectType.Node, nodes: [doc.getNode('node_k1ow3cbn')], }, new MouseEvent('mousedown', { clientX: 100, clientY: 100 }), ); const mockFn1 = jest.fn(); project.mountSimulator({ setCopyState: mockFn1 }); expect(dragon.getSimulators().size).toBe(1); fireEvent.keyDown(document, { ctrlKey: true }); expect(mockFn1).toHaveBeenCalled(); }); it('from', () => { const dragStartMockFn = jest.fn(); const dragMockFn = jest.fn(); const dragEndMockFn = jest.fn(); const offDragStart = dragon.onDragstart(dragStartMockFn); const offDrag = dragon.onDrag(dragMockFn); const offDragEnd = dragon.onDragend(dragEndMockFn); const mockBoostFn = jest .fn((e) => { return { type: IPublicEnumDragObjectType.Node, nodes: [doc.getNode('node_k1ow3cbn')], }; }) .mockImplementationOnce(() => null); const offFrom = dragon.from(document, mockBoostFn); // 无用 mouseDown,无效的按钮 fireEvent.mouseDown(document, { button: 2 }); expect(dragStartMockFn).not.toHaveBeenCalled(); // 无用 mouseDown,无效的 dragObject fireEvent.mouseDown(document, { clientX: 100, clientY: 100 }); expect(dragStartMockFn).not.toHaveBeenCalled(); fireEvent.mouseDown(document, { clientX: 100, clientY: 100 }); expect(dragStartMockFn).not.toHaveBeenCalled(); fireEvent.mouseMove(document, { clientX: 108, clientY: 108 }); expect(dragStartMockFn).toHaveBeenCalledTimes(1); expect(dragMockFn).toHaveBeenCalledTimes(1); fireEvent.mouseMove(document, { clientX: 110, clientY: 110 }); expect(dragMockFn).toHaveBeenCalledTimes(2); expect(dragon.dragging).toBeTruthy(); fireEvent.mouseUp(document, { clientX: 118, clientY: 118 }); expect(dragEndMockFn).toHaveBeenCalledTimes(1); offDragStart(); offDrag(); offDragEnd(); dragMockFn.mockClear(); fireEvent.mouseMove(document, { clientX: 100, clientY: 100 }); expect(dragMockFn).not.toHaveBeenCalled(); offFrom(); fireEvent.mouseMove(document, { clientX: 100, clientY: 100 }); expect(dragMockFn).not.toHaveBeenCalled(); }); it('addSensor / removeSensor', () => { const sensor = { locate: () => {}, sensorAvailable: true, isEnter: () => true, fixEvent: () => {}, deactiveSensor: () => {}, }; const sensor2 = {}; dragon.addSensor(sensor); expect(dragon.sensors.length).toBe(1); expect(dragon.activeSensor).toBeUndefined(); dragon.boost( { type: IPublicEnumDragObjectType.NodeData, data: [{ componentName: 'Button' }], }, new MouseEvent('mousedown', { clientX: 100, clientY: 100 }), ); fireEvent.mouseMove(document, { clientX: 108, clientY: 108 }); fireEvent.mouseMove(document, { clientX: 110, clientY: 110 }); fireEvent.mouseUp(document, { clientX: 118, clientY: 118 }); expect(dragon.activeSensor).toBe(sensor); // remove a non-existing sensor dragon.removeSensor(sensor2); expect(dragon.sensors.length).toBe(1); dragon.removeSensor(sensor); expect(dragon.sensors.length).toBe(0); }); it('has sensor', () => { const mockFn1 = jest.fn(); const mockDoc = document.createElement('iframe').contentWindow?.document; dragon.addSensor({ fixEvent: () => {}, locate: () => {}, contentDocument: mockDoc, }); project.mountSimulator({ setCopyState: mockFn1, setNativeSelection: () => {}, clearState: () => {}, setDraggingState: () => {}, }); const mockBoostFn = jest .fn((e) => { return { type: IPublicEnumDragObjectType.Node, nodes: [doc.getNode('node_k1ow3cbn')], }; }) .mockImplementationOnce(() => null); const offFrom = dragon.from(document, mockBoostFn); // TODO: 想办法 mock 一个 iframe.currentDocument fireEvent.mouseDown(document, { clientX: 100, clientY: 100 }); }); }); describe('导出的其他函数', () => { it('isDragNodeObject', () => { expect(isDragNodeObject({ type: IPublicEnumDragObjectType.Node, nodes: [] })).toBeTruthy(); }); it('isDragNodeDataObject', () => { expect(isDragNodeDataObject({ type: IPublicEnumDragObjectType.NodeData, data: [] })).toBeTruthy(); }); it('isDragAnyObject', () => { expect(isDragAnyObject()).toBeFalsy(); expect(isDragAnyObject({ type: IPublicEnumDragObjectType.Node, nodes: [] })).toBeFalsy(); expect(isDragAnyObject({ type: IPublicEnumDragObjectType.NodeData, data: [] })).toBeFalsy(); expect(isDragAnyObject({ type: 'others', data: [] })).toBeTruthy(); }); it('isLocateEvent', () => { expect(isLocateEvent({ type: 'LocateEvent' })).toBeTruthy(); }); it('isShaken', () => { expect( isShaken( { clientX: 1, clientY: 1, target: {} }, { clientX: 1, clientY: 1, target: { other: 1 } }, ), ).toBeTruthy(); expect(isShaken({ shaken: true })).toBeTruthy(); expect(isShaken({ clientX: 1, clientY: 1 }, { clientX: 2, clientY: 2 })).toBeFalsy(); expect(isShaken({ clientX: 1, clientY: 1 }, { clientX: 3, clientY: 5 })).toBeTruthy(); }); it('setShaken', () => { const e = {}; setShaken(e); expect(isShaken(e)).toBeTruthy(); }); it('isInvalidPoint', () => { expect(isInvalidPoint({ clientX: 0, clientY: 0 }, { clientX: 6, clientY: 1 })).toBeTruthy(); expect(isInvalidPoint({ clientX: 0, clientY: 0 }, { clientX: 1, clientY: 6 })).toBeTruthy(); expect(isInvalidPoint({ clientX: 0, clientY: 0 }, { clientX: 6, clientY: 6 })).toBeTruthy(); expect(isInvalidPoint({ clientX: 1, clientY: 1 }, { clientX: 2, clientY: 1 })).toBeFalsy(); }); it('isSameAs', () => { expect(isSameAs({ clientX: 1, clientY: 1 }, { clientX: 1, clientY: 1 })).toBeTruthy(); expect(isSameAs({ clientX: 1, clientY: 1 }, { clientX: 2, clientY: 1 })).toBeFalsy(); }); });