feat(modeling): crop connections on shape boundaries
Behind the scenes changes: * use diagram-js Matcher util in tests * add test cases for LayoutConnection * add test cases for CreateConnection * cleanup unused test diagram Related to #2
This commit is contained in:
parent
7347e484ba
commit
4afe3a80ed
|
@ -304,7 +304,9 @@ function BpmnRenderer(events, styles, pathMap) {
|
|||
);
|
||||
}
|
||||
|
||||
function createPathFromWaypoints(waypoints) {
|
||||
function createPathFromConnection(connection) {
|
||||
var waypoints = connection.waypoints;
|
||||
|
||||
var pathData = 'm ' + waypoints[0].x + ',' + waypoints[0].y;
|
||||
for (var i = 1; i < waypoints.length; i++) {
|
||||
pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' ';
|
||||
|
@ -1014,7 +1016,7 @@ function BpmnRenderer(events, styles, pathMap) {
|
|||
return drawDiamond(p, element.width, element.height);
|
||||
},
|
||||
'bpmn:SequenceFlow': function(p, element) {
|
||||
var pathData = createPathFromWaypoints(element.waypoints);
|
||||
var pathData = createPathFromConnection(element);
|
||||
var path = drawPath(p, pathData, {
|
||||
markerEnd: marker('sequenceflow-end')
|
||||
});
|
||||
|
@ -1062,7 +1064,7 @@ function BpmnRenderer(events, styles, pathMap) {
|
|||
|
||||
var di = getDi(element);
|
||||
|
||||
var pathData = createPathFromWaypoints(element.waypoints);
|
||||
var pathData = createPathFromConnection(element);
|
||||
var path = drawPath(p, pathData, {
|
||||
markerEnd: marker('messageflow-end'),
|
||||
markerStart: marker('messageflow-start'),
|
||||
|
|
|
@ -9,13 +9,40 @@ var Collections = require('diagram-js/lib/util/Collections');
|
|||
* A handler responsible for updating the underlying BPMN 2.0 XML + DI
|
||||
* once changes on the diagram happen
|
||||
*/
|
||||
function BpmnUpdater(eventBus, bpmnFactory) {
|
||||
function BpmnUpdater(eventBus, bpmnFactory, connectionDocking) {
|
||||
|
||||
this._eventBus = eventBus;
|
||||
this._bpmnFactory = bpmnFactory;
|
||||
|
||||
var self = this;
|
||||
|
||||
|
||||
|
||||
////// connection cropping /////////////////////////
|
||||
|
||||
// crop connection ends during create/update
|
||||
function cropConnection(e) {
|
||||
var context = e.context,
|
||||
connection;
|
||||
|
||||
if (!context.cropped) {
|
||||
connection = context.connection;
|
||||
connection.waypoints = connectionDocking.getCroppedWaypoints(connection);
|
||||
context.cropped = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.executed([ 'connection.layout', 'connection.create' ], cropConnection);
|
||||
|
||||
this.reverted([ 'connection.layout' ], function(e) {
|
||||
delete e.context.cropped;
|
||||
});
|
||||
|
||||
|
||||
|
||||
////// BPMN + DI update /////////////////////////
|
||||
|
||||
// create DI
|
||||
this.executed('shape.create', function(e) {
|
||||
self.createShapeDi(e.context.shape);
|
||||
});
|
||||
|
@ -25,6 +52,7 @@ function BpmnUpdater(eventBus, bpmnFactory) {
|
|||
});
|
||||
|
||||
|
||||
// update parent
|
||||
function updateShapeParent(e) {
|
||||
self.updateShapeParent(e.context.shape || e.context.connection);
|
||||
}
|
||||
|
@ -33,6 +61,7 @@ function BpmnUpdater(eventBus, bpmnFactory) {
|
|||
this.reverted([ 'shape.move', 'shape.create', 'connection.create' ], updateShapeParent);
|
||||
|
||||
|
||||
// update bounds
|
||||
function updateBounds(e) {
|
||||
self.updateBounds(e.context.shape);
|
||||
}
|
||||
|
@ -40,17 +69,28 @@ function BpmnUpdater(eventBus, bpmnFactory) {
|
|||
this.executed([ 'shape.move' ], updateBounds);
|
||||
this.reverted([ 'shape.move' ], updateBounds);
|
||||
|
||||
|
||||
// attach / detach connection
|
||||
function updateConnection(e) {
|
||||
self.updateConnection(e.context.connection);
|
||||
}
|
||||
|
||||
this.executed([ 'connection.create' ], updateConnection);
|
||||
this.reverted([ 'connection.create' ], updateConnection);
|
||||
|
||||
|
||||
// update waypoints
|
||||
function updateConnectionWaypoints(e) {
|
||||
self.updateConnectionWaypoints(e.context.connection);
|
||||
}
|
||||
|
||||
this.executed([ 'connection.layout' ], updateConnectionWaypoints);
|
||||
this.reverted([ 'connection.layout' ], updateConnectionWaypoints);
|
||||
}
|
||||
|
||||
module.exports = BpmnUpdater;
|
||||
|
||||
BpmnUpdater.$inject = [ 'eventBus', 'bpmnFactory' ];
|
||||
BpmnUpdater.$inject = [ 'eventBus', 'bpmnFactory', 'connectionDocking'];
|
||||
|
||||
|
||||
/////// implementation //////////////////////////////////
|
||||
|
@ -65,6 +105,7 @@ BpmnUpdater.prototype.createShapeDi = function(shape) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
BpmnUpdater.prototype.createConnectionDi = function(connection) {
|
||||
var businessObject = connection.businessObject;
|
||||
if (!businessObject.di) {
|
||||
|
@ -74,6 +115,7 @@ BpmnUpdater.prototype.createConnectionDi = function(connection) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
BpmnUpdater.prototype.updateShapeParent = function(shape) {
|
||||
var parentShape = shape.parent;
|
||||
|
||||
|
@ -86,6 +128,7 @@ BpmnUpdater.prototype.updateShapeParent = function(shape) {
|
|||
this.updateDiParent(businessObject.di, parentDi);
|
||||
};
|
||||
|
||||
|
||||
BpmnUpdater.prototype.updateBounds = function(shape) {
|
||||
|
||||
var di = shape.businessObject.di;
|
||||
|
@ -98,6 +141,7 @@ BpmnUpdater.prototype.updateBounds = function(shape) {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
BpmnUpdater.prototype.updateDiParent = function(di, parentDi) {
|
||||
|
||||
if (parentDi && !parentDi.$instanceOf('bpmndi:BPMNPlane')) {
|
||||
|
@ -145,6 +189,11 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
|
|||
};
|
||||
|
||||
|
||||
BpmnUpdater.prototype.updateConnectionWaypoints = function(connection) {
|
||||
connection.businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints));
|
||||
};
|
||||
|
||||
|
||||
BpmnUpdater.prototype.updateConnection = function(connection) {
|
||||
|
||||
var businessObject = connection.businessObject,
|
||||
|
|
|
@ -11,5 +11,5 @@ module.exports = {
|
|||
modeling: [ 'type', require('./Modeling') ],
|
||||
labelSupport: [ 'type', require('./LabelSupport') ],
|
||||
layouter: [ 'type', require('diagram-js/lib/features/modeling/Layouter') ],
|
||||
connectionLayouter: [ 'type', require('diagram-js/lib/layout/CroppingConnectionLayouter') ]
|
||||
connectionDocking: [ 'type', require('diagram-js/lib/layout/CroppingConnectionDocking') ]
|
||||
};
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="simple" targetNamespace="http://bpmn.io/schema/bpmn">
|
||||
<bpmn2:process id="Process_1" isExecutable="false">
|
||||
<bpmn2:endEvent id="EndEvent_1" name="End Event 1">
|
||||
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
<bpmn2:task id="Task_1" name="Task 1"/>
|
||||
<bpmn2:exclusiveGateway id="Gateway_1" name="Gateway 1
">
|
||||
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
|
||||
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
|
||||
</bpmn2:exclusiveGateway>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_2" name="Sequence Flow 2" sourceRef="Gateway_1" targetRef="EndEvent_1"/>
|
||||
<bpmn2:task id="Task_2" name="Task 3">
|
||||
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_1" name="Sequence Flow 1" sourceRef="Gateway_1" targetRef="Task_2"/>
|
||||
<bpmn2:task id="Task_3" name="Task 2"/>
|
||||
</bpmn2:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_2" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="708.0" y="144.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="22.0" width="65.0" x="694.0" y="185.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_3" bpmnElement="Task_2">
|
||||
<dc:Bounds height="80.0" width="100.0" x="732.0" y="396.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_4" bpmnElement="Task_1">
|
||||
<dc:Bounds height="80.0" width="100.0" x="192.0" y="336.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_2" bpmnElement="Gateway_1" isMarkerVisible="true">
|
||||
<dc:Bounds height="50.0" width="50.0" x="528.0" y="316.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="553.0" y="371.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_6" bpmnElement="Task_3">
|
||||
<dc:Bounds height="80.0" width="100.0" x="348.0" y="122.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_6" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_EndEvent_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="553.0" y="316.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="553.0" y="162.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="708.0" y="162.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="22.0" width="106.0" x="564.0" y="240.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_7" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_Task_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="578.0" y="341.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="934.0" y="341.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="934.0" y="436.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="832.0" y="436.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="22.0" width="47.0" x="831.0" y="312.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn2:definitions>
|
|
@ -1,120 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_zQGpIK9BEeOZpaQF18vcig" targetNamespace="http://activiti.org/bpmn">
|
||||
<bpmn2:process id="Process_1" isExecutable="false">
|
||||
<bpmn2:startEvent id="StartEvent_1" name="Process
started">
|
||||
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
|
||||
</bpmn2:startEvent>
|
||||
<bpmn2:task id="Task_1" name="First task in the process">
|
||||
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="Task_1"/>
|
||||
<bpmn2:exclusiveGateway id="ExclusiveGateway_1" name="question?">
|
||||
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
|
||||
<bpmn2:outgoing>SequenceFlow_4</bpmn2:outgoing>
|
||||
</bpmn2:exclusiveGateway>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="Task_1" targetRef="ExclusiveGateway_1"/>
|
||||
<bpmn2:task id="Task_2" name="task for ok">
|
||||
<bpmn2:incoming>SequenceFlow_3</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_3" name="ok" sourceRef="ExclusiveGateway_1" targetRef="Task_2"/>
|
||||
<bpmn2:task id="Task_3" name="task for not ok">
|
||||
<bpmn2:incoming>SequenceFlow_4</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_4" name="not ok" sourceRef="ExclusiveGateway_1" targetRef="Task_3"/>
|
||||
<bpmn2:exclusiveGateway id="ExclusiveGateway_2">
|
||||
<bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
|
||||
<bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_7</bpmn2:outgoing>
|
||||
</bpmn2:exclusiveGateway>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="Task_2" targetRef="ExclusiveGateway_2"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_6" name="" sourceRef="Task_3" targetRef="ExclusiveGateway_2"/>
|
||||
<bpmn2:task id="Task_4" name="task with crazy characters 
*+üäö/!?">
|
||||
<bpmn2:incoming>SequenceFlow_7</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_8</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_7" name="" sourceRef="ExclusiveGateway_2" targetRef="Task_4"/>
|
||||
<bpmn2:endEvent id="EndEvent_1" name="Process
ended">
|
||||
<bpmn2:incoming>SequenceFlow_8</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_8" name="" sourceRef="Task_4" targetRef="EndEvent_1"/>
|
||||
</bpmn2:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_5" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="250.0" y="252.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_2" bpmnElement="Task_1">
|
||||
<dc:Bounds height="80.0" width="100.0" x="336.0" y="230.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_5" targetElement="_BPMNShape_Task_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="286.0" y="270.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="336.0" y="270.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_2" bpmnElement="ExclusiveGateway_1" isMarkerVisible="true">
|
||||
<dc:Bounds height="50.0" width="50.0" x="486.0" y="245.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="22.0" width="62.0" x="480.0" y="216.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_Task_2" targetElement="_BPMNShape_ExclusiveGateway_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="436.0" y="270.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="486.0" y="270.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_3" bpmnElement="Task_2">
|
||||
<dc:Bounds height="80.0" width="100.0" x="586.0" y="230.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_3" bpmnElement="SequenceFlow_3" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_Task_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="536.0" y="270.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="586.0" y="270.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="22.0" width="20.0" x="540.0" y="270.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_4" bpmnElement="Task_3">
|
||||
<dc:Bounds height="80.0" width="100.0" x="586.0" y="330.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_4" bpmnElement="SequenceFlow_4" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_Task_4">
|
||||
<di:waypoint xsi:type="dc:Point" x="511.0" y="295.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="511.0" y="370.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="586.0" y="370.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="22.0" width="42.0" x="516.0" y="374.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_3" bpmnElement="ExclusiveGateway_2" isMarkerVisible="true">
|
||||
<dc:Bounds height="50.0" width="50.0" x="736.0" y="245.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_5" bpmnElement="SequenceFlow_5" sourceElement="_BPMNShape_Task_3" targetElement="_BPMNShape_ExclusiveGateway_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="686.0" y="270.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="736.0" y="270.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_6" bpmnElement="SequenceFlow_6" sourceElement="_BPMNShape_Task_4" targetElement="_BPMNShape_ExclusiveGateway_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="686.0" y="370.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="711.0" y="370.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="761.0" y="370.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="761.0" y="295.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="758.0" y="370.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_5" bpmnElement="Task_4">
|
||||
<dc:Bounds height="80.0" width="100.0" x="836.0" y="230.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_7" bpmnElement="SequenceFlow_7" sourceElement="_BPMNShape_ExclusiveGateway_3" targetElement="_BPMNShape_Task_5">
|
||||
<di:waypoint xsi:type="dc:Point" x="786.0" y="270.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="836.0" y="270.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_8" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="986.0" y="252.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_8" bpmnElement="SequenceFlow_8" sourceElement="_BPMNShape_Task_5" targetElement="_BPMNShape_EndEvent_8">
|
||||
<di:waypoint xsi:type="dc:Point" x="936.0" y="270.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="986.0" y="270.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn2:definitions>
|
|
@ -1,52 +1 @@
|
|||
var jsondiffpatch = require('jsondiffpatch'),
|
||||
_ = require('lodash');
|
||||
|
||||
|
||||
var compare = jsondiffpatch.create({
|
||||
objectHash: function (obj) {
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function deepEquals(actual, expected) {
|
||||
var actualClone = _.cloneDeep(actual);
|
||||
var expectedClone = _.cloneDeep(expected);
|
||||
|
||||
var result = {
|
||||
pass: _.isEqual(actualClone, expectedClone)
|
||||
};
|
||||
|
||||
if (!result.pass) {
|
||||
console.error('[to-deep-equal] elements do not equal. diff: ', compare.diff(actualClone, expectedClone), false, 4);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function wrap(isOld, callback) {
|
||||
if (isOld) {
|
||||
return function(expected) {
|
||||
return callback(expected, this.actual).pass;
|
||||
};
|
||||
} else {
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
|
||||
function addMatchers() {
|
||||
|
||||
// DIRTY HACK DDDSZZZ
|
||||
// Remove when we got jasmin 2.x in browser AND node env
|
||||
|
||||
var old = !jasmine.addMatchers;
|
||||
|
||||
(old ? this : jasmine).addMatchers({
|
||||
|
||||
toDeepEqual: wrap(old, function(actual, expected) {
|
||||
return deepEquals(actual, expected);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.add = addMatchers;
|
||||
module.exports = require('diagram-js/test/Matchers');
|
|
@ -13,7 +13,7 @@ var Modeler = require('../../../lib/Modeler');
|
|||
|
||||
describe('modeler', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var container;
|
||||
|
|
|
@ -13,7 +13,7 @@ var Viewer = require('../../../lib/Viewer');
|
|||
|
||||
describe('viewer', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var container;
|
||||
|
|
|
@ -11,7 +11,7 @@ var fs = require('fs');
|
|||
|
||||
describe('draw - bpmn renderer', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
it('should render activity markers', function(done) {
|
||||
|
|
|
@ -14,7 +14,7 @@ var contextPadModule = require('../../../../../lib/features/context-pad'),
|
|||
|
||||
describe('features - context-pad', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/complex.bpmn', 'utf-8');
|
||||
|
|
|
@ -19,7 +19,7 @@ var LabelUtil = require('../../../../../lib/features/label-editing/LabelUtil');
|
|||
|
||||
describe('features - label-editing', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/features/label-editing/labels.bpmn', 'utf-8');
|
||||
|
|
|
@ -16,7 +16,7 @@ var labelEditingModule = require('../../../../../lib/features/label-editing'),
|
|||
|
||||
describe('direct editing - touch integration', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var container;
|
||||
|
|
|
@ -15,7 +15,7 @@ var modelingModule = require('../../../../../lib/features/modeling'),
|
|||
|
||||
describe('features/modeling - append shape', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
||||
|
@ -315,13 +315,13 @@ describe('features/modeling - append shape', function() {
|
|||
|
||||
describe('ExclusiveGateway', function() {
|
||||
|
||||
it('should append', inject(function(elementRegistry, bpmnModeling) {
|
||||
it('should append', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||
|
||||
// when
|
||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:ExclusiveGateway'),
|
||||
target = targetShape.businessObject;
|
||||
|
||||
// then
|
||||
|
@ -330,7 +330,7 @@ describe('features/modeling - append shape', function() {
|
|||
}));
|
||||
|
||||
|
||||
it('should add to parent (sub process)', inject(function(elementRegistry, bpmnModeling) {
|
||||
it('should add to parent (sub process)', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||
|
@ -340,7 +340,7 @@ describe('features/modeling - append shape', function() {
|
|||
subProcess = subProcessShape.businessObject;
|
||||
|
||||
// when
|
||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:ExclusiveGateway'),
|
||||
target = targetShape.businessObject;
|
||||
|
||||
// then
|
||||
|
@ -348,7 +348,7 @@ describe('features/modeling - append shape', function() {
|
|||
}));
|
||||
|
||||
|
||||
it('should undo append', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
||||
it('should undo append', inject(function(elementRegistry, modeling, commandStack) {
|
||||
|
||||
// given
|
||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||
|
@ -357,7 +357,7 @@ describe('features/modeling - append shape', function() {
|
|||
var startEvent = startEventShape.businessObject,
|
||||
subProcess = subProcessShape.businessObject;
|
||||
|
||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:ExclusiveGateway'),
|
||||
target = targetShape.businessObject;
|
||||
|
||||
// when
|
||||
|
|
|
@ -13,7 +13,7 @@ var modelingModule = require('../../../../../lib/features/modeling');
|
|||
|
||||
xdescribe('features - bpmn-factory', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
'use strict';
|
||||
|
||||
var Matchers = require('../../../Matchers'),
|
||||
TestHelper = require('../../../TestHelper');
|
||||
|
||||
/* global bootstrapBpmnJS, inject */
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var modelingModule = require('../../../../../lib/features/modeling'),
|
||||
drawModule = require('../../../../../lib/draw');
|
||||
|
||||
|
||||
describe('features/modeling - create connection', function() {
|
||||
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/sequence-flows.bpmn', 'utf-8');
|
||||
|
||||
var testModules = [ drawModule, modelingModule ];
|
||||
|
||||
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
||||
|
||||
|
||||
describe('connection handling', function() {
|
||||
|
||||
it('should execute', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var taskShape = elementRegistry.getById('Task_1'),
|
||||
task = taskShape.businessObject,
|
||||
gatewayShape = elementRegistry.getById('Gateway_1'),
|
||||
gateway = gatewayShape.businessObject;
|
||||
|
||||
|
||||
// when
|
||||
var sequenceFlowConnection = modeling.createConnection(taskShape, gatewayShape, {
|
||||
type: 'bpmn:SequenceFlow',
|
||||
}, taskShape.parent);
|
||||
|
||||
var sequenceFlow = sequenceFlowConnection.businessObject;
|
||||
|
||||
// then
|
||||
expect(sequenceFlowConnection).toBeDefined();
|
||||
expect(sequenceFlow).toBeDefined();
|
||||
|
||||
expect(sequenceFlow.sourceRef).toBe(task);
|
||||
expect(sequenceFlow.targetRef).toBe(gateway);
|
||||
|
||||
expect(task.outgoing).toContain(sequenceFlow);
|
||||
expect(gateway.incoming).toContain(sequenceFlow);
|
||||
|
||||
expect(sequenceFlow.di.$parent).toBe(task.di.$parent);
|
||||
expect(sequenceFlow.di.$parent.planeElement).toContain(sequenceFlow.di);
|
||||
|
||||
// expect cropped connection
|
||||
expect(sequenceFlowConnection.waypoints).toDeepEqual([
|
||||
{ original: { x: 242, y: 376 }, x: 292, y: 370 },
|
||||
{ original: { x: 553, y: 341 }, x: 531, y: 344 }
|
||||
]);
|
||||
|
||||
// expect cropped waypoints in di
|
||||
expect(sequenceFlow.di.waypoint).toDeepEqual([
|
||||
{ $type: 'dc:Point', x: 292, y: 370 },
|
||||
{ $type: 'dc:Point', x: 531, y: 344 }
|
||||
]);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('undo support', function() {
|
||||
|
||||
it('should undo', inject(function(elementRegistry, commandStack, modeling) {
|
||||
|
||||
// given
|
||||
var taskShape = elementRegistry.getById('Task_1'),
|
||||
task = taskShape.businessObject,
|
||||
gatewayShape = elementRegistry.getById('Gateway_1'),
|
||||
gateway = gatewayShape.businessObject;
|
||||
|
||||
|
||||
var sequenceFlowConnection = modeling.createConnection(taskShape, gatewayShape, {
|
||||
type: 'bpmn:SequenceFlow',
|
||||
}, taskShape.parent);
|
||||
|
||||
var sequenceFlow = sequenceFlowConnection.businessObject;
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then
|
||||
expect(sequenceFlow.$parent).toBe(null);
|
||||
expect(sequenceFlow.sourceRef).toBe(null);
|
||||
expect(sequenceFlow.targetRef).toBe(null);
|
||||
|
||||
expect(task.outgoing).not.toContain(sequenceFlow);
|
||||
expect(gateway.incoming).not.toContain(sequenceFlow);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('redo support', function() {
|
||||
|
||||
it('should redo', inject(function(elementRegistry, commandStack, modeling) {
|
||||
|
||||
// given
|
||||
var taskShape = elementRegistry.getById('Task_1'),
|
||||
task = taskShape.businessObject,
|
||||
gatewayShape = elementRegistry.getById('Gateway_1'),
|
||||
gateway = gatewayShape.businessObject;
|
||||
|
||||
|
||||
var sequenceFlowConnection = modeling.createConnection(taskShape, gatewayShape, {
|
||||
type: 'bpmn:SequenceFlow',
|
||||
}, taskShape.parent);
|
||||
|
||||
var sequenceFlow = sequenceFlowConnection.businessObject;
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
commandStack.redo();
|
||||
|
||||
// then
|
||||
expect(sequenceFlow.sourceRef).toBe(task);
|
||||
expect(sequenceFlow.targetRef).toBe(gateway);
|
||||
|
||||
expect(task.outgoing).toContain(sequenceFlow);
|
||||
expect(gateway.incoming).toContain(sequenceFlow);
|
||||
|
||||
expect(sequenceFlow.di.$parent).toBe(task.di.$parent);
|
||||
expect(sequenceFlow.di.$parent.planeElement).toContain(sequenceFlow.di);
|
||||
|
||||
// expect cropped connection
|
||||
expect(sequenceFlowConnection.waypoints).toDeepEqual([
|
||||
{ original: { x: 242, y: 376 }, x: 292, y: 370 },
|
||||
{ original: { x: 553, y: 341 }, x: 531, y: 344 }
|
||||
]);
|
||||
|
||||
// expect cropped waypoints in di
|
||||
expect(sequenceFlow.di.waypoint).toDeepEqual([
|
||||
{ $type: 'dc:Point', x: 292, y: 370 },
|
||||
{ $type: 'dc:Point', x: 531, y: 344 }
|
||||
]);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,106 @@
|
|||
'use strict';
|
||||
|
||||
var Matchers = require('../../../Matchers'),
|
||||
TestHelper = require('../../../TestHelper');
|
||||
|
||||
/* global bootstrapBpmnJS, inject */
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var modelingModule = require('../../../../../lib/features/modeling'),
|
||||
drawModule = require('../../../../../lib/draw');
|
||||
|
||||
|
||||
describe('features/modeling - layout connection', function() {
|
||||
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/sequence-flows.bpmn', 'utf-8');
|
||||
|
||||
var testModules = [ drawModule, modelingModule ];
|
||||
|
||||
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
||||
|
||||
|
||||
describe('connection handling', function() {
|
||||
|
||||
it('should execute', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var sequenceFlowConnection = elementRegistry.getById('SequenceFlow_1'),
|
||||
sequenceFlow = sequenceFlowConnection.businessObject;
|
||||
|
||||
|
||||
// when
|
||||
modeling.layoutConnection(sequenceFlowConnection);
|
||||
|
||||
// then
|
||||
|
||||
// expect cropped connection
|
||||
expect(sequenceFlowConnection.waypoints).toDeepEqual([
|
||||
{ original: { x: 553, y: 341 }, x: 571, y: 348 },
|
||||
{ original: { x: 782, y: 436 }, x: 732, y: 415 }
|
||||
]);
|
||||
|
||||
// expect cropped waypoints in di
|
||||
expect(sequenceFlow.di.waypoint).toDeepEqual([
|
||||
{ $type: 'dc:Point', x: 571, y: 348 },
|
||||
{ $type: 'dc:Point', x: 732, y: 415 }
|
||||
]);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('undo support', function() {
|
||||
|
||||
it('should undo', inject(function(elementRegistry, commandStack, modeling) {
|
||||
|
||||
// given
|
||||
var sequenceFlowConnection = elementRegistry.getById('SequenceFlow_1'),
|
||||
sequenceFlow = sequenceFlowConnection.businessObject;
|
||||
|
||||
var oldWaypoints = sequenceFlowConnection.waypoints,
|
||||
oldDiWaypoints = sequenceFlow.di.waypoint;
|
||||
|
||||
modeling.layoutConnection(sequenceFlowConnection);
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then
|
||||
expect(sequenceFlowConnection.waypoints).toDeepEqual(oldWaypoints);
|
||||
expect(sequenceFlow.di.waypoint).toDeepEqual(oldDiWaypoints);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('redo support', function() {
|
||||
|
||||
it('should redo', inject(function(elementRegistry, commandStack, modeling) {
|
||||
|
||||
// given
|
||||
var sequenceFlowConnection = elementRegistry.getById('SequenceFlow_1'),
|
||||
sequenceFlow = sequenceFlowConnection.businessObject;
|
||||
|
||||
modeling.layoutConnection(sequenceFlowConnection);
|
||||
|
||||
var newWaypoints = sequenceFlowConnection.waypoints,
|
||||
newDiWaypoints = sequenceFlow.di.waypoint;
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
commandStack.redo();
|
||||
|
||||
// then
|
||||
expect(sequenceFlowConnection.waypoints).toDeepEqual(newWaypoints);
|
||||
expect(sequenceFlow.di.waypoint).toDeepEqual(newDiWaypoints);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -15,7 +15,7 @@ var modelingModule = require('../../../../../lib/features/modeling'),
|
|||
|
||||
describe('features/modeling - move shape', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
||||
|
|
|
@ -15,7 +15,7 @@ var touchModule = require('../../../../../lib/features/touch'),
|
|||
|
||||
describe('features - touch', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/complex.bpmn', 'utf-8');
|
||||
|
|
|
@ -17,7 +17,7 @@ var zoomscrollModule = require('../../../../../lib/features/zoomscroll'),
|
|||
|
||||
describe('features - zoomscroll', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/complex.bpmn', 'utf-8');
|
||||
|
|
|
@ -22,7 +22,7 @@ describe('import - importer', function() {
|
|||
return BpmnModel.fromXML(xml, 'bpmn:Definitions', opts, callback);
|
||||
}
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
var container;
|
||||
|
|
|
@ -11,7 +11,7 @@ var fs = require('fs');
|
|||
|
||||
describe('import - collapsed container', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
describe('in process', function() {
|
||||
|
|
|
@ -11,7 +11,7 @@ var fs = require('fs');
|
|||
|
||||
describe('import - labels', function() {
|
||||
|
||||
beforeEach(Matchers.add);
|
||||
beforeEach(Matchers.addDeepEquals);
|
||||
|
||||
|
||||
describe('should import embedded labels', function() {
|
||||
|
|
Loading…
Reference in New Issue