mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-12 03:01:16 +00:00
test(selection & dragon): add some test cases for increasing code coverage rate
This commit is contained in:
parent
b4d7d6d8c2
commit
c50b07d3ec
@ -2,35 +2,7 @@ import { EventEmitter } from 'events';
|
||||
import { ISimulatorHost } from '../../simulator';
|
||||
import { Designer, Point } from '../../designer';
|
||||
import { cursor } from '@alilc/lowcode-utils';
|
||||
// import Cursor from './cursor';
|
||||
// import Pages from './pages';
|
||||
|
||||
function makeEventsHandler(
|
||||
boostEvent: MouseEvent | DragEvent,
|
||||
sensors: ISimulatorHost[],
|
||||
): (fn: (sdoc: Document) => void) => void {
|
||||
const topDoc = window.document;
|
||||
const sourceDoc = boostEvent.view?.document || topDoc;
|
||||
// TODO: optimize this logic, reduce listener
|
||||
// const boostPrevented = boostEvent.defaultPrevented;
|
||||
const docs = new Set<Document>();
|
||||
// if (boostPrevented || isDragEvent(boostEvent)) {
|
||||
docs.add(topDoc);
|
||||
// }
|
||||
docs.add(sourceDoc);
|
||||
// if (sourceDoc !== topDoc || isDragEvent(boostEvent)) {
|
||||
sensors.forEach(sim => {
|
||||
const sdoc = sim.contentDocument;
|
||||
if (sdoc) {
|
||||
docs.add(sdoc);
|
||||
}
|
||||
});
|
||||
// }
|
||||
|
||||
return (handle: (sdoc: Document) => void) => {
|
||||
docs.forEach(doc => handle(doc));
|
||||
};
|
||||
}
|
||||
import { makeEventsHandler } from '../../utils/misc';
|
||||
|
||||
// 拖动缩放
|
||||
export default class DragResizeEngine {
|
||||
@ -73,6 +45,7 @@ export default class DragResizeEngine {
|
||||
|
||||
const masterSensors = this.getMasterSensors();
|
||||
|
||||
/* istanbul ignore next */
|
||||
const createResizeEvent = (e: MouseEvent | DragEvent): Point => {
|
||||
const sourceDocument = e.view?.document;
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import { DropLocation } from './location';
|
||||
import { Node, DocumentModel } from '../document';
|
||||
import { ISimulatorHost, isSimulatorHost, NodeInstance, ComponentInstance } from '../simulator';
|
||||
import { Designer } from './designer';
|
||||
import { makeEventsHandler } from '../utils/misc';
|
||||
|
||||
export interface LocateEvent {
|
||||
readonly type: 'LocateEvent';
|
||||
@ -135,7 +136,7 @@ export function isShaken(e1: MouseEvent | DragEvent, e2: MouseEvent | DragEvent)
|
||||
);
|
||||
}
|
||||
|
||||
function isInvalidPoint(e: any, last: any): boolean {
|
||||
export function isInvalidPoint(e: any, last: any): boolean {
|
||||
return (
|
||||
e.clientX === 0 &&
|
||||
e.clientY === 0 &&
|
||||
@ -144,7 +145,7 @@ function isInvalidPoint(e: any, last: any): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function isSameAs(e1: MouseEvent | DragEvent, e2: MouseEvent | DragEvent): boolean {
|
||||
export function isSameAs(e1: MouseEvent | DragEvent, e2: MouseEvent | DragEvent): boolean {
|
||||
return e1.clientY === e2.clientY && e1.clientX === e2.clientX;
|
||||
}
|
||||
|
||||
@ -159,31 +160,6 @@ function getSourceSensor(dragObject: DragObject): ISimulatorHost | null {
|
||||
return dragObject.nodes[0]?.document.simulator || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* make a handler that listen all sensors:document, avoid frame lost
|
||||
*/
|
||||
function makeEventsHandler(
|
||||
boostEvent: MouseEvent | DragEvent,
|
||||
sensors: ISimulatorHost[],
|
||||
): (fn: (sdoc: Document) => void) => void {
|
||||
const topDoc = window.document;
|
||||
const sourceDoc = boostEvent.view?.document || topDoc;
|
||||
// TODO: optimize this logic, reduce listener
|
||||
const docs = new Set<Document>();
|
||||
docs.add(topDoc);
|
||||
docs.add(sourceDoc);
|
||||
sensors.forEach((sim) => {
|
||||
const sdoc = sim.contentDocument;
|
||||
if (sdoc) {
|
||||
docs.add(sdoc);
|
||||
}
|
||||
});
|
||||
|
||||
return (handle: (sdoc: Document) => void) => {
|
||||
docs.forEach((doc) => handle(doc));
|
||||
};
|
||||
}
|
||||
|
||||
function isDragEvent(e: any): e is DragEvent {
|
||||
return e?.type?.startsWith('drag');
|
||||
}
|
||||
@ -325,6 +301,7 @@ export class Dragon {
|
||||
const locateEvent = createLocateEvent(e);
|
||||
const sensor = chooseSensor(locateEvent);
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (isRGL) {
|
||||
// 禁止被拖拽元素的阻断
|
||||
const nodeInst = dragObject.nodes[0].getDOMNode();
|
||||
@ -429,6 +406,7 @@ export class Dragon {
|
||||
// 发送drop事件
|
||||
if (e) {
|
||||
const { isRGL, rglNode } = getRGL(e);
|
||||
/* istanbul ignore next */
|
||||
if (isRGL && this._canDrop) {
|
||||
const tarNode = dragObject.nodes[0];
|
||||
if (rglNode.id !== tarNode.id) {
|
||||
@ -468,7 +446,7 @@ export class Dragon {
|
||||
this._dragging = false;
|
||||
try {
|
||||
this.emitter.emit('dragend', { dragObject, copy });
|
||||
} catch (ex) {
|
||||
} catch (ex) /* istanbul ignore next */ {
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
@ -489,6 +467,7 @@ export class Dragon {
|
||||
doc.removeEventListener('keydown', checkcopy, false);
|
||||
doc.removeEventListener('keyup', checkcopy, false);
|
||||
});
|
||||
/* istanbul ignore next */
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
@ -509,7 +488,7 @@ export class Dragon {
|
||||
if (!sourceDocument || sourceDocument === document) {
|
||||
evt.globalX = e.clientX;
|
||||
evt.globalY = e.clientY;
|
||||
} /* istanbul ignore next */ else {
|
||||
} else /* istanbul ignore next */ {
|
||||
// event from simulator sandbox
|
||||
let srcSim: ISimulatorHost | undefined;
|
||||
const lastSim = lastSensor && isSimulatorHost(lastSensor) ? lastSensor : null;
|
||||
@ -616,6 +595,7 @@ export class Dragon {
|
||||
}
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
private getMasterSensors(): ISimulatorHost[] {
|
||||
return Array.from(
|
||||
new Set(
|
||||
|
||||
@ -147,10 +147,11 @@ export class Selection {
|
||||
if (n === PositionNO.Contains || n === PositionNO.TheSame) {
|
||||
isTop = false;
|
||||
break;
|
||||
}
|
||||
// node contains nodes[i], delete nodes[i]
|
||||
if (n === PositionNO.ContainedBy) {
|
||||
} else if (n === PositionNO.ContainedBy) {
|
||||
// node contains nodes[i], delete nodes[i]
|
||||
nodes.splice(i, 1);
|
||||
} else {
|
||||
isTop = false;
|
||||
}
|
||||
}
|
||||
// node is top item, push to nodes
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import Viewport from '../builtin-simulator/viewport';
|
||||
import { ISimulatorHost } from '../simulator';
|
||||
|
||||
export function isElementNode(domNode: Element) {
|
||||
return domNode.nodeType === Node.ELEMENT_NODE;
|
||||
@ -28,4 +29,28 @@ export function isDOMNodeVisible(domNode: Element, viewport: Viewport) {
|
||||
*/
|
||||
export function normalizeTriggers(triggers: string[]) {
|
||||
return triggers.map((trigger: string) => trigger?.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* make a handler that listen all sensors:document, avoid frame lost
|
||||
*/
|
||||
export function makeEventsHandler(
|
||||
boostEvent: MouseEvent | DragEvent,
|
||||
sensors: ISimulatorHost[],
|
||||
): (fn: (sdoc: Document) => void) => void {
|
||||
const topDoc = window.document;
|
||||
const sourceDoc = boostEvent.view?.document || topDoc;
|
||||
const docs = new Set<Document>();
|
||||
docs.add(topDoc);
|
||||
docs.add(sourceDoc);
|
||||
sensors.forEach((sim) => {
|
||||
const sdoc = sim.contentDocument;
|
||||
if (sdoc) {
|
||||
docs.add(sdoc);
|
||||
}
|
||||
});
|
||||
|
||||
return (handle: (sdoc: Document) => void) => {
|
||||
docs.forEach((doc) => handle(doc));
|
||||
};
|
||||
}
|
||||
@ -57,7 +57,8 @@ describe('DragResizeEngine 测试', () => {
|
||||
});
|
||||
|
||||
// do nothing
|
||||
resizeEngine.from();
|
||||
const noop = resizeEngine.from();
|
||||
noop();
|
||||
|
||||
const offFrom = resizeEngine.from(document, 'e', mockedBoostFn);
|
||||
|
||||
|
||||
@ -1,14 +1,18 @@
|
||||
import { Detecting } from '../../src/designer/detecting';
|
||||
|
||||
it('Detecting 测试', () => {
|
||||
const fn = jest.fn();
|
||||
const detecting = new Detecting();
|
||||
detecting.onDetectingChange(fn);
|
||||
|
||||
expect(detecting.enable).toBeTruthy();
|
||||
|
||||
const mockNode = { document };
|
||||
detecting.capture(mockNode);
|
||||
expect(fn).toHaveBeenCalledWith(detecting.current);
|
||||
expect(detecting.current).toBe(mockNode);
|
||||
|
||||
detecting.release({});
|
||||
detecting.release(mockNode);
|
||||
expect(detecting.current).toBeNull();
|
||||
|
||||
|
||||
@ -3,16 +3,6 @@ import { set } from '../utils';
|
||||
import { Editor, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { Project } from '../../src/project/project';
|
||||
import { DocumentModel } from '../../src/document/document-model';
|
||||
import {
|
||||
isRootNode,
|
||||
Node,
|
||||
isNode,
|
||||
comparePosition,
|
||||
contains,
|
||||
insertChild,
|
||||
insertChildren,
|
||||
PositionNO,
|
||||
} from '../../src/document/node/node';
|
||||
import { Designer } from '../../src/designer/designer';
|
||||
import {
|
||||
Dragon,
|
||||
@ -23,12 +13,10 @@ import {
|
||||
DragObjectType,
|
||||
isShaken,
|
||||
setShaken,
|
||||
isInvalidPoint,
|
||||
isSameAs,
|
||||
} from '../../src/designer/dragon';
|
||||
import formSchema from '../fixtures/schema/form';
|
||||
import divMetadata from '../fixtures/component-metadata/div';
|
||||
import formMetadata from '../fixtures/component-metadata/form';
|
||||
import otherMeta from '../fixtures/component-metadata/other';
|
||||
import pageMetadata from '../fixtures/component-metadata/page';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
|
||||
describe('Dragon 测试', () => {
|
||||
@ -273,9 +261,32 @@ describe('Dragon 测试', () => {
|
||||
});
|
||||
|
||||
it('addSensor / removeSensor', () => {
|
||||
const sensor = {};
|
||||
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: DragObjectType.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);
|
||||
});
|
||||
@ -343,4 +354,16 @@ describe('导出的其他函数', () => {
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
@ -67,6 +67,7 @@ describe('选择区测试', () => {
|
||||
expect(selection.selected).toEqual(['node_k1ow3cbj', 'form']);
|
||||
selectionChangeHandler.mockClear();
|
||||
|
||||
selection.remove('node_k1ow3cbj_fake');
|
||||
selection.remove('node_k1ow3cbj');
|
||||
expect(selectionChangeHandler).toHaveBeenCalledTimes(1);
|
||||
expect(selectionChangeHandler.mock.calls[0][0]).toEqual(['form']);
|
||||
@ -141,7 +142,7 @@ describe('选择区测试', () => {
|
||||
selectionChangeHandler.mockClear();
|
||||
});
|
||||
|
||||
it('dispose 方法', () => {
|
||||
it('dispose 方法 - 选中的节点没有被删除的', () => {
|
||||
const project = new Project(designer, {
|
||||
componentsTree: [
|
||||
formSchema,
|
||||
@ -152,16 +153,13 @@ describe('选择区测试', () => {
|
||||
const { currentDocument } = project;
|
||||
const { nodesMap, selection } = currentDocument!;
|
||||
|
||||
selection.selectAll(['form', 'node_k1ow3cbj', 'form2']);
|
||||
selection.selectAll(['form', 'node_k1ow3cbj']);
|
||||
|
||||
const selectionChangeHandler = jest.fn();
|
||||
selection.onSelectionChange(selectionChangeHandler);
|
||||
selection.dispose();
|
||||
|
||||
expect(selectionChangeHandler).toHaveBeenCalledTimes(1);
|
||||
expect(selectionChangeHandler.mock.calls[0][0]).toEqual(['form', 'node_k1ow3cbj']);
|
||||
expect(selection.selected).toEqual(['form', 'node_k1ow3cbj']);
|
||||
selectionChangeHandler.mockClear();
|
||||
expect(selectionChangeHandler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('containsNode 方法', () => {
|
||||
@ -242,4 +240,36 @@ describe('选择区测试', () => {
|
||||
expect(selection.selected).toEqual(['page']);
|
||||
selectionChangeHandler.mockClear();
|
||||
});
|
||||
|
||||
it('getNodes', () => {
|
||||
const project = new Project(designer, {
|
||||
componentsTree: [
|
||||
formSchema,
|
||||
],
|
||||
});
|
||||
project.open();
|
||||
const { currentDocument } = project;
|
||||
const { selection } = currentDocument!;
|
||||
|
||||
selection.selectAll(['form', 'node_k1ow3cbj', 'form2']);
|
||||
|
||||
// form2 is not a valid node
|
||||
expect(selection.getNodes()).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('getTopNodes', () => {
|
||||
const project = new Project(designer, {
|
||||
componentsTree: [
|
||||
formSchema,
|
||||
],
|
||||
});
|
||||
project.open();
|
||||
const { currentDocument } = project;
|
||||
const { selection } = currentDocument!;
|
||||
|
||||
selection.selectAll(['node_k1ow3cbj', 'node_k1ow3cbo', 'form', 'node_k1ow3cbl', 'form2']);
|
||||
|
||||
// form2 is not a valid node, and node_k1ow3cbj is a child node of form
|
||||
expect(selection.getTopNodes()).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import { isElementNode, isDOMNodeVisible, normalizeTriggers } from '../../src/utils/misc';
|
||||
import { isElementNode, isDOMNodeVisible, normalizeTriggers, makeEventsHandler } from '../../src/utils/misc';
|
||||
|
||||
it('isElementNode', () => {
|
||||
expect(isElementNode(document.createElement('div'))).toBeTruthy();
|
||||
@ -152,3 +152,13 @@ describe('isDOMNodeVisible', () => {
|
||||
it('normalizeTriggers', () => {
|
||||
expect(normalizeTriggers(['n', 'w'])).toEqual(['N', 'W']);
|
||||
});
|
||||
|
||||
it('makeEventsHandler', () => {
|
||||
const sensor = { contentDocument: document };
|
||||
// no contentDocument
|
||||
const sensor2 = {};
|
||||
const bind = makeEventsHandler({ view: { document } } as any, [sensor, sensor2]);
|
||||
const fn = jest.fn();
|
||||
bind((doc) => fn(doc));
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user