feat(modeling): add move onto sequence flow

This adds the ability to move flow nodes onto existing
sequence flows (similar to the create on flow behavior
implemented with an earlier bpmn-js release).

Closes camunda/camunda-modeler#432
This commit is contained in:
Ricardo Matias 2017-01-25 17:27:30 +01:00 committed by Nico Rehwaldt
parent 6dc4af5396
commit def402971c
7 changed files with 519 additions and 270 deletions

View File

@ -1,95 +0,0 @@
'use strict';
var inherits = require('inherits');
var assign = require('lodash/object/assign');
var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
var getApproxIntersection = require('diagram-js/lib/util/LineIntersection').getApproxIntersection;
function copy(obj) {
return assign({}, obj);
}
function CreateOnFlowBehavior(eventBus, bpmnRules, modeling) {
CommandInterceptor.call(this, eventBus);
/**
* Reconnect start / end of a connection after
* dropping an element on a flow.
*/
this.preExecute('shape.create', function(context) {
var parent = context.parent,
shape = context.shape;
if (bpmnRules.canInsert(shape, parent)) {
context.targetFlow = parent;
context.parent = parent.parent;
}
}, true);
this.postExecute('shape.create', function(context) {
var shape = context.shape,
targetFlow = context.targetFlow,
position = context.position,
source,
target,
reconnected,
intersection,
waypoints,
waypointsBefore,
waypointsAfter,
dockingPoint;
if (targetFlow) {
waypoints = targetFlow.waypoints;
intersection = getApproxIntersection(waypoints, position);
if (intersection) {
waypointsBefore = waypoints.slice(0, intersection.index);
waypointsAfter = waypoints.slice(intersection.index + (intersection.bendpoint ? 1 : 0));
dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : position;
waypointsBefore.push(copy(dockingPoint));
waypointsAfter.unshift(copy(dockingPoint));
}
source = targetFlow.source;
target = targetFlow.target;
if (bpmnRules.canConnect(source, shape, targetFlow)) {
// reconnect source -> inserted shape
modeling.reconnectEnd(targetFlow, shape, waypointsBefore || copy(position));
reconnected = true;
}
if (bpmnRules.canConnect(shape, target, targetFlow)) {
if (!reconnected) {
// reconnect inserted shape -> end
modeling.reconnectStart(targetFlow, shape, waypointsAfter || copy(position));
} else {
modeling.connect(shape, target, { type: targetFlow.type, waypoints: waypointsAfter });
}
}
}
}, true);
}
inherits(CreateOnFlowBehavior, CommandInterceptor);
CreateOnFlowBehavior.$inject = [ 'eventBus', 'bpmnRules', 'modeling' ];
module.exports = CreateOnFlowBehavior;

View File

@ -0,0 +1,121 @@
'use strict';
var inherits = require('inherits');
var assign = require('lodash/object/assign');
var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
var getApproxIntersection = require('diagram-js/lib/util/LineIntersection').getApproxIntersection;
function copy(obj) {
return assign({}, obj);
}
function DropOnFlow(eventBus, bpmnRules, modeling) {
CommandInterceptor.call(this, eventBus);
/**
* Reconnect start / end of a connection after
* dropping an element on a flow.
*/
function insertShape(shape, targetFlow, position) {
var waypoints = targetFlow.waypoints,
waypointsBefore, waypointsAfter, dockingPoint, source, target, reconnected;
var intersection = getApproxIntersection(waypoints, position);
if (intersection) {
waypointsBefore = waypoints.slice(0, intersection.index);
waypointsAfter = waypoints.slice(intersection.index + (intersection.bendpoint ? 1 : 0));
dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : position;
waypointsBefore.push(copy(dockingPoint));
waypointsAfter.unshift(copy(dockingPoint));
}
source = targetFlow.source;
target = targetFlow.target;
if (bpmnRules.canConnect(source, shape, targetFlow)) {
// reconnect source -> inserted shape
modeling.reconnectEnd(targetFlow, shape, waypointsBefore || position);
reconnected = true;
}
if (bpmnRules.canConnect(shape, target, targetFlow)) {
if (!reconnected) {
// reconnect inserted shape -> end
modeling.reconnectStart(targetFlow, shape, waypointsAfter || position);
} else {
modeling.connect(shape, target, { type: targetFlow.type, waypoints: waypointsAfter });
}
}
}
eventBus.on('shape.move.move', 250, function(event) {
var context = event.context,
target = context.target,
targetFlow = context.targetFlow,
shape = context.shape,
shapes = context.shapes;
if (shapes.length === 1 && bpmnRules.canInsert(shape, target)) {
context.targetFlow = target;
context.target = target.parent;
} else if (targetFlow) {
context.targetFlow = context.flowParent = null;
}
});
eventBus.on('shape.move.end', 250, function(event) {
var context = event.context,
shape = context.shape,
targetFlow = context.targetFlow,
position = {
x: shape.x + (shape.width / 2),
y: shape.y + (shape.height / 2)
};
if (targetFlow) {
insertShape(shape, targetFlow, position);
}
}, true);
this.preExecute('shape.create', function(context) {
var parent = context.parent,
shape = context.shape;
if (bpmnRules.canInsert(shape, parent)) {
context.targetFlow = parent;
context.parent = parent.parent;
}
}, true);
this.postExecute('shape.create', function(context) {
var shape = context.shape,
targetFlow = context.targetFlow,
position = context.position;
if (targetFlow) {
insertShape(shape, targetFlow, position);
}
}, true);
}
inherits(DropOnFlow, CommandInterceptor);
DropOnFlow.$inject = [ 'eventBus', 'bpmnRules', 'modeling' ];
module.exports = DropOnFlow;

View File

@ -4,7 +4,7 @@ module.exports = {
'copyPasteBehavior',
'createBoundaryEventBehavior',
'createDataObjectBehavior',
'createOnFlowBehavior',
'dropOnFlowBehavior',
'createParticipantBehavior',
'dataInputAssociationBehavior',
'deleteLaneBehavior',
@ -25,7 +25,7 @@ module.exports = {
copyPasteBehavior: [ 'type', require('./CopyPasteBehavior') ],
createBoundaryEventBehavior: [ 'type', require('./CreateBoundaryEventBehavior') ],
createDataObjectBehavior: [ 'type', require('./CreateDataObjectBehavior') ],
createOnFlowBehavior: [ 'type', require('./CreateOnFlowBehavior') ],
dropOnFlowBehavior: [ 'type', require('./DropOnFlowBehavior') ],
createParticipantBehavior: [ 'type', require('./CreateParticipantBehavior') ],
dataInputAssociationBehavior: [ 'type', require('./DataInputAssociationBehavior') ],
deleteLaneBehavior: [ 'type', require('./DeleteLaneBehavior') ],

View File

@ -83,7 +83,8 @@ BpmnRules.prototype.init = function() {
return canAttach(shapes, target, null, position) ||
canReplace(shapes, target, position) ||
canMove(shapes, target, position);
canMove(shapes, target, position) ||
canInsert(shapes, target, position);
});
this.addRule([ 'shape.create', 'shape.append' ], function(context) {
@ -749,6 +750,14 @@ function canConnectDataAssociation(source, target) {
function canInsert(shape, flow, position) {
if (Array.isArray(shape)) {
if (shape.length !== 1) {
return false;
}
shape = shape[0];
}
// return true if we can drop on the
// underlying flow parent
//

View File

@ -1,171 +0,0 @@
'use strict';
require('../../../../TestHelper');
/* global inject, bootstrapModeler */
var flatten = require('lodash/array/flatten');
var modelingModule = require('../../../../../lib/features/modeling');
describe('modeling/behavior - drop on connection', function() {
var diagramXML = require('./CreateOnFlowBehavior.bpmn');
beforeEach(bootstrapModeler(diagramXML, { modules: modelingModule }));
describe('rules', function() {
it('should be allowed for an IntermediateThrowEvent', inject(function(elementRegistry, bpmnRules, elementFactory) {
// when
var sequenceFlow = elementRegistry.get('SequenceFlow');
var intermediateThrowEvent = elementFactory.createShape({ type: 'bpmn:IntermediateThrowEvent' });
// then
expect(bpmnRules.canCreate(intermediateThrowEvent, sequenceFlow)).to.be.true;
}));
});
describe('execution', function() {
it('should connect start -> target -> end', inject(function(modeling, elementRegistry, elementFactory) {
// given
var intermediateThrowEvent = elementFactory.createShape({ type: 'bpmn:IntermediateThrowEvent' });
var startEvent = elementRegistry.get('StartEvent'),
sequenceFlow = elementRegistry.get('SequenceFlow'),
task = elementRegistry.get('Task');
var originalWaypoints = sequenceFlow.waypoints;
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var newShape = modeling.createShape(intermediateThrowEvent, dropPosition, sequenceFlow);
// then
var targetConnection = newShape.outgoing[0];
// new incoming connection
expect(newShape.incoming.length).to.equal(1);
expect(newShape.incoming[0]).to.eql(sequenceFlow);
// new outgoing connection
expect(newShape.outgoing.length).to.equal(1);
expect(targetConnection).to.be.ok;
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
expect(startEvent.outgoing[0]).to.equal(newShape.incoming[0]);
expect(task.incoming[0]).to.equal(newShape.outgoing[0]);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
{ x: 322, y: 120 }
]));
expect(sequenceFlow).to.have.endDocking(dropPosition);
expect(targetConnection).to.have.waypoints(flatten([
{ x: 340, y: 138 },
originalWaypoints.slice(2)
]));
expect(targetConnection).to.have.startDocking(dropPosition);
}));
it('should connect start -> target', inject(function(modeling, elementRegistry, elementFactory) {
// given
var endEventShape = elementFactory.createShape({ type: 'bpmn:EndEvent' });
var sequenceFlow = elementRegistry.get('SequenceFlow');
var originalWaypoints = sequenceFlow.waypoints;
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var newShape = modeling.createShape(endEventShape, dropPosition, sequenceFlow);
// then
// new incoming connection
expect(newShape.incoming.length).to.equal(1);
expect(newShape.incoming[0]).to.eql(sequenceFlow);
// no outgoing edges
expect(newShape.outgoing.length).to.equal(0);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
{ x: 322, y: 120 }
]));
}));
it('should connect target -> end', inject(function(modeling, elementRegistry, elementFactory) {
// given
var startEventShape = elementFactory.createShape({ type: 'bpmn:StartEvent' });
var sequenceFlow = elementRegistry.get('SequenceFlow');
var originalWaypoints = sequenceFlow.waypoints;
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var newShape = modeling.createShape(startEventShape, dropPosition, sequenceFlow);
// then
// no incoming connection
expect(newShape.incoming.length).to.equal(0);
// no outgoing edges
expect(newShape.outgoing.length).to.equal(1);
expect(newShape.outgoing[0]).to.eql(sequenceFlow);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
{ x: 340, y: 138 },
originalWaypoints.slice(2)
]));
}));
});
describe('rules', function() {
it('should not insert participant', inject(function(rules, elementRegistry, elementFactory) {
// given
var participantShape = elementFactory.createShape({ type: 'bpmn:Participant' });
var sequenceFlow = elementRegistry.get('SequenceFlow');
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var canDrop = rules.allowed('shape.create', {
shape: participantShape,
parent: sequenceFlow,
dropPosition: dropPosition
});
// then
expect(canDrop).to.be.false;
}));
});
});

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.7.0-dev">
<bpmn:process id="Process" isExecutable="false">
<bpmn:startEvent id="StartEvent">
<bpmn:outgoing>SequenceFlow</bpmn:outgoing>
@ -8,6 +8,9 @@
<bpmn:incoming>SequenceFlow</bpmn:incoming>
</bpmn:task>
<bpmn:sequenceFlow id="SequenceFlow" sourceRef="StartEvent" targetRef="Task" />
<bpmn:intermediateThrowEvent id="IntermediateThrowEvent_foo" />
<bpmn:endEvent id="EndEvent_foo" />
<bpmn:startEvent id="StartEvent_foo" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process">
@ -26,6 +29,24 @@
<dc:Bounds x="297.5" y="110" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="IntermediateThrowEvent_foo_di" bpmnElement="IntermediateThrowEvent_foo">
<dc:Bounds x="173" y="192" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="191" y="228" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="EndEvent_foo_di" bpmnElement="EndEvent_foo">
<dc:Bounds x="173" y="281" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="191" y="317" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="StartEvent_foo_di" bpmnElement="StartEvent_foo">
<dc:Bounds x="534" y="192" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="552" y="228" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,364 @@
'use strict';
require('../../../../TestHelper');
/* global inject, bootstrapModeler */
var flatten = require('lodash/array/flatten');
var coreModule = require('../../../../../lib/core'),
moveModule = require('diagram-js/lib/features/move'),
modelingModule = require('../../../../../lib/features/modeling'),
noTouchInteractionModule = { touchInteractionEvents: ['value', null ] };
var canvasEvent = require('../../../../util/MockEvents').createCanvasEvent;
describe('modeling/behavior - drop on connection', function() {
var diagramXML = require('./DropOnFlowBehavior.bpmn');
var testModules = [ noTouchInteractionModule, moveModule, modelingModule, coreModule ];
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
describe('rules', function() {
it('should be allowed for an IntermediateThrowEvent', inject(function(elementRegistry, bpmnRules, elementFactory) {
// when
var sequenceFlow = elementRegistry.get('SequenceFlow');
var intermediateThrowEvent = elementFactory.createShape({ type: 'bpmn:IntermediateThrowEvent' });
// then
expect(bpmnRules.canCreate(intermediateThrowEvent, sequenceFlow)).to.be.true;
}));
});
describe('execution', function() {
describe('create', function() {
it('should connect start -> target -> end', inject(function(modeling, elementRegistry, elementFactory) {
// given
var intermediateThrowEvent = elementFactory.createShape({ type: 'bpmn:IntermediateThrowEvent' });
var startEvent = elementRegistry.get('StartEvent'),
sequenceFlow = elementRegistry.get('SequenceFlow'),
task = elementRegistry.get('Task');
var originalWaypoints = sequenceFlow.waypoints;
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var newShape = modeling.createShape(intermediateThrowEvent, dropPosition, sequenceFlow);
// then
var targetConnection = newShape.outgoing[0];
// new incoming connection
expect(newShape.incoming.length).to.equal(1);
expect(newShape.incoming[0]).to.eql(sequenceFlow);
// new outgoing connection
expect(newShape.outgoing.length).to.equal(1);
expect(targetConnection).to.be.ok;
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
expect(startEvent.outgoing[0]).to.equal(newShape.incoming[0]);
expect(task.incoming[0]).to.equal(newShape.outgoing[0]);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
{ x: 322, y: 120 }
]));
expect(sequenceFlow).to.have.endDocking(dropPosition);
expect(targetConnection).to.have.waypoints(flatten([
{ x: 340, y: 138 },
originalWaypoints.slice(2)
]));
expect(targetConnection).to.have.startDocking(dropPosition);
}));
it('should connect start -> target', inject(function(modeling, elementRegistry, elementFactory) {
// given
var endEventShape = elementFactory.createShape({ type: 'bpmn:EndEvent' });
var sequenceFlow = elementRegistry.get('SequenceFlow');
var originalWaypoints = sequenceFlow.waypoints;
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var newShape = modeling.createShape(endEventShape, dropPosition, sequenceFlow);
// then
// new incoming connection
expect(newShape.incoming.length).to.equal(1);
expect(newShape.incoming[0]).to.eql(sequenceFlow);
// no outgoing edges
expect(newShape.outgoing.length).to.equal(0);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
{ x: 322, y: 120 }
]));
}));
it('should connect target -> end', inject(function(modeling, elementRegistry, elementFactory) {
// given
var startEventShape = elementFactory.createShape({ type: 'bpmn:StartEvent' });
var sequenceFlow = elementRegistry.get('SequenceFlow');
var originalWaypoints = sequenceFlow.waypoints;
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var newShape = modeling.createShape(startEventShape, dropPosition, sequenceFlow);
// then
// no incoming connection
expect(newShape.incoming.length).to.equal(0);
// no outgoing edges
expect(newShape.outgoing.length).to.equal(1);
expect(newShape.outgoing[0]).to.eql(sequenceFlow);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
{ x: 340, y: 138 },
originalWaypoints.slice(2)
]));
}));
});
describe('move', function() {
beforeEach(inject(function(dragging) {
dragging.setOptions({ manual: true });
}));
it('should connect start -> target -> end', inject(function(dragging, move, elementRegistry, selection) {
// given
var intermediateThrowEvent = elementRegistry.get('IntermediateThrowEvent_foo');
var startEvent = elementRegistry.get('StartEvent'),
sequenceFlow = elementRegistry.get('SequenceFlow'),
sequenceFlowGfx = elementRegistry.getGraphics(sequenceFlow),
task = elementRegistry.get('Task');
var originalWaypoints = sequenceFlow.waypoints;
// when
selection.select(intermediateThrowEvent);
move.start(canvasEvent({ x: 0, y: 0 }), intermediateThrowEvent);
dragging.hover({
element: sequenceFlow,
gfx: sequenceFlowGfx
});
dragging.move(canvasEvent({ x: 150, y: 0 }));
dragging.end();
// then
var targetConnection = intermediateThrowEvent.outgoing[0];
// new incoming connection
expect(intermediateThrowEvent.incoming.length).to.equal(1);
expect(intermediateThrowEvent.incoming[0]).to.eql(sequenceFlow);
// new outgoing connection
expect(intermediateThrowEvent.outgoing.length).to.equal(1);
expect(targetConnection).to.be.ok;
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
expect(startEvent.outgoing[0]).to.equal(intermediateThrowEvent.incoming[0]);
expect(task.incoming[0]).to.equal(intermediateThrowEvent.outgoing[0]);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 2),
{ x: 341, y: 192 }
]));
expect(sequenceFlow).to.have.endDocking({ x: 341, y: 210 });
expect(targetConnection).to.have.waypoints(flatten([
{ x: 341, y: 228 },
originalWaypoints.slice(2)
]));
expect(targetConnection).to.have.startDocking({ x: 341, y: 210 });
}));
it('should connect start -> target', inject(function(modeling, elementRegistry, selection, move, dragging) {
// given
var endEventShape = elementRegistry.get('EndEvent_foo');
var sequenceFlow = elementRegistry.get('SequenceFlow'),
sequenceFlowGfx = elementRegistry.getGraphics(sequenceFlow),
originalWaypoints = sequenceFlow.waypoints;
// when
selection.select(endEventShape);
move.start(canvasEvent({ x: 0, y: 0 }), endEventShape);
dragging.hover({
element: sequenceFlow,
gfx: sequenceFlowGfx
});
dragging.move(canvasEvent({ x: 150, y: 0 }));
dragging.end();
// then
// new incoming connection
expect(endEventShape.incoming.length).to.equal(1);
expect(endEventShape.incoming[0]).to.eql(sequenceFlow);
// no outgoing edges
expect(endEventShape.outgoing.length).to.equal(0);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 2),
{ x: 340, y: 281 }
]));
}));
it('should connect target -> end', inject(function(modeling, elementRegistry, dragging, selection, move) {
var startEventShape = elementRegistry.get('StartEvent_foo');
var sequenceFlow = elementRegistry.get('SequenceFlow'),
sequenceFlowGfx = elementRegistry.getGraphics(sequenceFlow),
originalWaypoints = sequenceFlow.waypoints;
// when
selection.select(startEventShape);
move.start(canvasEvent({ x: 0, y: 0 }), startEventShape);
dragging.hover({
element: sequenceFlow,
gfx: sequenceFlowGfx
});
dragging.move(canvasEvent({ x: -215, y: 0 }));
dragging.end();
// then
// no incoming connection
expect(startEventShape.incoming.length).to.equal(0);
// no outgoing edges
expect(startEventShape.outgoing.length).to.equal(1);
expect(startEventShape.outgoing[0]).to.eql(sequenceFlow);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
{ x: 338, y: 228 },
originalWaypoints.slice(2)
]));
}));
});
});
describe('rules', function() {
it('should not insert participant', inject(function(rules, elementRegistry, elementFactory) {
// given
var participantShape = elementFactory.createShape({ type: 'bpmn:Participant' });
var sequenceFlow = elementRegistry.get('SequenceFlow');
var dropPosition = { x: 340, y: 120 }; // first bendpoint
// when
var canDrop = rules.allowed('shape.create', {
shape: participantShape,
parent: sequenceFlow,
dropPosition: dropPosition
});
// then
expect(canDrop).to.be.false;
}));
it('should not insert multiple with "move"', inject(function(elementRegistry, selection, move, dragging) {
// given
var intermediateThrowEvent = elementRegistry.get('IntermediateThrowEvent_foo'),
endEventShape = elementRegistry.get('EndEvent_foo');
var sequenceFlow = elementRegistry.get('SequenceFlow'),
sequenceFlowGfx = elementRegistry.getGraphics(sequenceFlow);
var intInitPosition = {
x: intermediateThrowEvent.x,
y: intermediateThrowEvent.y
},
endInitPosition = {
x: endEventShape.x,
y: endEventShape.y
};
selection.select([ intermediateThrowEvent, endEventShape ]);
// when
move.start(canvasEvent({ x: 0, y: 0 }), intermediateThrowEvent);
dragging.hover({
element: sequenceFlow,
gfx: sequenceFlowGfx
});
dragging.move(canvasEvent({ x: -215, y: 0 }));
dragging.end();
// then
expect(intermediateThrowEvent).to.have.position(intInitPosition);
expect(endEventShape).to.have.position(endInitPosition);
}));
});
});