test(selection & dragon): add some test cases for increasing code coverage rate

This commit is contained in:
LeoYuan 袁力皓 2022-08-08 16:50:44 +08:00 committed by LeoYuan 袁力皓
parent b4d7d6d8c2
commit c50b07d3ec
9 changed files with 131 additions and 84 deletions

View File

@ -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;

View File

@ -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(

View File

@ -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

View File

@ -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));
};
}

View File

@ -57,7 +57,8 @@ describe('DragResizeEngine 测试', () => {
});
// do nothing
resizeEngine.from();
const noop = resizeEngine.from();
noop();
const offFrom = resizeEngine.from(document, 'e', mockedBoostFn);

View File

@ -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();

View File

@ -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();
});
});

View File

@ -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);
});
});

View File

@ -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);
});