feat(features/modeling): implement BPMN update for shape+label move
Related to #2
This commit is contained in:
parent
9f68cb4cf7
commit
bc61e6c3ed
|
@ -41,6 +41,13 @@ BpmnFactory.prototype.create = function(type, attrs) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BpmnFactory.prototype.createDiLabel = function() {
|
||||||
|
return this.create('bpmndi:BPMNLabel', {
|
||||||
|
bounds: this.createDiBounds()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
BpmnFactory.prototype.createDiShape = function(semantic, bounds, attrs) {
|
BpmnFactory.prototype.createDiShape = function(semantic, bounds, attrs) {
|
||||||
|
|
||||||
return this.create('bpmndi:BPMNShape', _.extend({
|
return this.create('bpmndi:BPMNShape', _.extend({
|
||||||
|
|
|
@ -33,6 +33,13 @@ function BpmnUpdater(eventBus, bpmnFactory) {
|
||||||
this.reverted([ 'shape.move', 'shape.create', 'connection.create' ], updateShapeParent);
|
this.reverted([ 'shape.move', 'shape.create', 'connection.create' ], updateShapeParent);
|
||||||
|
|
||||||
|
|
||||||
|
function updateBounds(e) {
|
||||||
|
self.updateBounds(e.context.shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.executed([ 'shape.move' ], updateBounds);
|
||||||
|
this.reverted([ 'shape.move' ], updateBounds);
|
||||||
|
|
||||||
function updateConnection(e) {
|
function updateConnection(e) {
|
||||||
self.updateConnection(e.context.connection);
|
self.updateConnection(e.context.connection);
|
||||||
}
|
}
|
||||||
|
@ -79,6 +86,18 @@ BpmnUpdater.prototype.updateShapeParent = function(shape) {
|
||||||
this.updateDiParent(businessObject.di, parentDi);
|
this.updateDiParent(businessObject.di, parentDi);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.updateBounds = function(shape) {
|
||||||
|
|
||||||
|
var di = shape.businessObject.di;
|
||||||
|
|
||||||
|
var bounds = shape.type === 'label' ? this._getLabel(di).bounds : di.bounds;
|
||||||
|
|
||||||
|
_.extend(bounds, {
|
||||||
|
x: shape.x,
|
||||||
|
y: shape.y
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
BpmnUpdater.prototype.updateDiParent = function(di, parentDi) {
|
BpmnUpdater.prototype.updateDiParent = function(di, parentDi) {
|
||||||
|
|
||||||
if (parentDi && !parentDi.$instanceOf('bpmndi:BPMNPlane')) {
|
if (parentDi && !parentDi.$instanceOf('bpmndi:BPMNPlane')) {
|
||||||
|
@ -158,6 +177,13 @@ BpmnUpdater.prototype.updateConnection = function(connection) {
|
||||||
|
|
||||||
/////// helpers /////////////////////////////////////////
|
/////// helpers /////////////////////////////////////////
|
||||||
|
|
||||||
|
BpmnUpdater.prototype._getLabel = function(di) {
|
||||||
|
if (!di.label) {
|
||||||
|
di.label = this._bpmnFactory.createDiLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
return di.label;
|
||||||
|
};
|
||||||
|
|
||||||
BpmnUpdater.prototype.pre = function(commands, callback) {
|
BpmnUpdater.prototype.pre = function(commands, callback) {
|
||||||
this.on(commands, 'preExecute', callback);
|
this.on(commands, 'preExecute', callback);
|
||||||
|
|
|
@ -7,7 +7,11 @@ var BaseModeling = require('diagram-js/lib/features/modeling/Modeling');
|
||||||
var AppendShapeHandler = require('./cmd/AppendShapeHandler'),
|
var AppendShapeHandler = require('./cmd/AppendShapeHandler'),
|
||||||
CreateShapeHandler = require('diagram-js/lib/features/modeling/cmd/CreateShapeHandler'),
|
CreateShapeHandler = require('diagram-js/lib/features/modeling/cmd/CreateShapeHandler'),
|
||||||
CreateConnectionHandler = require('diagram-js/lib/features/modeling/cmd/CreateConnectionHandler'),
|
CreateConnectionHandler = require('diagram-js/lib/features/modeling/cmd/CreateConnectionHandler'),
|
||||||
CreateLabelHandler = require('diagram-js/lib/features/modeling/cmd/CreateLabelHandler');
|
CreateLabelHandler = require('diagram-js/lib/features/modeling/cmd/CreateLabelHandler'),
|
||||||
|
|
||||||
|
LayoutConnectionHandler = require('diagram-js/lib/features/modeling/cmd/LayoutConnectionHandler'),
|
||||||
|
|
||||||
|
MoveShapeHandler = require('diagram-js/lib/features/modeling/cmd/MoveShapeHandler');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,10 +32,15 @@ module.exports = Modeling;
|
||||||
|
|
||||||
|
|
||||||
Modeling.prototype.registerHandlers = function(commandStack) {
|
Modeling.prototype.registerHandlers = function(commandStack) {
|
||||||
commandStack.registerHandler('shape.appendShape', AppendShapeHandler);
|
|
||||||
commandStack.registerHandler('shape.create', CreateShapeHandler);
|
commandStack.registerHandler('shape.create', CreateShapeHandler);
|
||||||
commandStack.registerHandler('connection.create', CreateConnectionHandler);
|
commandStack.registerHandler('shape.move', MoveShapeHandler);
|
||||||
|
|
||||||
|
commandStack.registerHandler('shape.append', AppendShapeHandler);
|
||||||
|
|
||||||
commandStack.registerHandler('label.create', CreateLabelHandler);
|
commandStack.registerHandler('label.create', CreateLabelHandler);
|
||||||
|
|
||||||
|
commandStack.registerHandler('connection.create', CreateConnectionHandler);
|
||||||
|
commandStack.registerHandler('connection.layout', LayoutConnectionHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,5 +10,6 @@ module.exports = {
|
||||||
elementFactory: [ 'type', require('./ElementFactory') ],
|
elementFactory: [ 'type', require('./ElementFactory') ],
|
||||||
modeling: [ 'type', require('./Modeling') ],
|
modeling: [ 'type', require('./Modeling') ],
|
||||||
labelSupport: [ 'type', require('./LabelSupport') ],
|
labelSupport: [ 'type', require('./LabelSupport') ],
|
||||||
layouter: [ 'type', require('diagram-js/lib/features/modeling/Layouter') ]
|
layouter: [ 'type', require('diagram-js/lib/features/modeling/Layouter') ],
|
||||||
|
connectionLayouter: [ 'type', require('diagram-js/lib/layout/CroppingConnectionLayouter') ]
|
||||||
};
|
};
|
|
@ -0,0 +1,375 @@
|
||||||
|
'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 - append shape', function() {
|
||||||
|
|
||||||
|
beforeEach(Matchers.add);
|
||||||
|
|
||||||
|
|
||||||
|
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
||||||
|
|
||||||
|
var testModules = [ drawModule, modelingModule ];
|
||||||
|
|
||||||
|
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
describe('shape handling', function() {
|
||||||
|
|
||||||
|
it('should execute', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(targetShape).toBeDefined();
|
||||||
|
expect(target.$instanceOf('bpmn:Task')).toBe(true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should create DI', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(target.di).toBeDefined();
|
||||||
|
expect(target.di.$parent).toBe(startEvent.di.$parent);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should add to parent (sub process)', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(subProcess.get('flowElements')).toContain(target);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should add shape label', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:EndEvent'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(targetShape.label).toBeDefined();
|
||||||
|
expect(elementRegistry.getById(targetShape.label.id)).toBeDefined();
|
||||||
|
|
||||||
|
expect(target.di.label).toBeDefined();
|
||||||
|
|
||||||
|
expect(target.di.label.bounds.x).toBe(targetShape.label.x);
|
||||||
|
expect(target.di.label.bounds.y).toBe(targetShape.label.y);
|
||||||
|
expect(target.di.label.bounds.width).toBe(targetShape.label.width);
|
||||||
|
expect(target.di.label.bounds.height).toBe(targetShape.label.height);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should add connection', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
return e.sourceRef === startEvent && e.targetRef === target;
|
||||||
|
});
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).toBeDefined();
|
||||||
|
expect(connection.$instanceOf('bpmn:SequenceFlow')).toBe(true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('undo support', function() {
|
||||||
|
|
||||||
|
it('should undo add to parent', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(subProcess.get('flowElements')).not.toContain(target);
|
||||||
|
expect(subProcess.di.$parent.get('planeElement')).not.toContain(target.di);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo add shape label', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:EndEvent'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
return e.sourceRef === startEvent && e.targetRef === target;
|
||||||
|
});
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection.sourceRef).toBe(null);
|
||||||
|
expect(connection.targetRef).toBe(null);
|
||||||
|
expect(connection.$parent).toBe(null);
|
||||||
|
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
||||||
|
|
||||||
|
expect(targetShape.label).not.toBeDefined();
|
||||||
|
expect(elementRegistry.getById(target.id + '_label')).not.toBeDefined();
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo add connection', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
return e.sourceRef === startEvent && e.targetRef === target;
|
||||||
|
});
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection.sourceRef).toBe(null);
|
||||||
|
expect(connection.targetRef).toBe(null);
|
||||||
|
|
||||||
|
expect(startEvent.get('outgoing')).not.toContain(connection);
|
||||||
|
expect(target.get('incoming')).not.toContain(connection);
|
||||||
|
|
||||||
|
expect(connection.$parent).toBe(null);
|
||||||
|
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
||||||
|
|
||||||
|
expect(elementRegistry.getById(targetShape.id)).not.toBeDefined();
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo add connection label', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
return e.sourceRef === startEvent && e.targetRef === target;
|
||||||
|
});
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection.sourceRef).toBe(null);
|
||||||
|
expect(connection.targetRef).toBe(null);
|
||||||
|
expect(connection.$parent).toBe(null);
|
||||||
|
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
||||||
|
|
||||||
|
expect(elementRegistry.getById(connection.id + '_label')).not.toBeDefined();
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should redo appending multiple shapes', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape2 = modeling.appendFlowNode(targetShape, 'bpmn:UserTask');
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.redo();
|
||||||
|
commandStack.redo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
// expect redo to work on original target object
|
||||||
|
expect(targetShape.parent).toBe(subProcessShape);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(targetShape2.parent).toBe(null);
|
||||||
|
expect(elementRegistry.getById(targetShape2.id)).not.toBeDefined();
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should redo add connection', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
return e.sourceRef === startEvent && e.targetRef === target;
|
||||||
|
});
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.redo();
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection.sourceRef).toBe(null);
|
||||||
|
expect(connection.targetRef).toBe(null);
|
||||||
|
expect(connection.$parent).toBe(null);
|
||||||
|
|
||||||
|
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('bpmn element support', function() {
|
||||||
|
|
||||||
|
describe('ExclusiveGateway', function() {
|
||||||
|
|
||||||
|
it('should append', inject(function(elementRegistry, bpmnModeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(targetShape).toBeDefined();
|
||||||
|
expect(target.$instanceOf('bpmn:ExclusiveGateway')).toBe(true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should add to parent (sub process)', inject(function(elementRegistry, bpmnModeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(subProcess.get('flowElements')).toContain(target);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo append', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(subProcess.get('flowElements')).not.toContain(target);
|
||||||
|
expect(subProcess.di.$parent.get('planeElement')).not.toContain(target.di);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -1,368 +0,0 @@
|
||||||
'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 - bpmn-modeling', function() {
|
|
||||||
|
|
||||||
beforeEach(Matchers.add);
|
|
||||||
|
|
||||||
|
|
||||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
|
||||||
|
|
||||||
var testModules = [ modelingModule, drawModule ];
|
|
||||||
|
|
||||||
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
|
||||||
|
|
||||||
|
|
||||||
describe('commands', function() {
|
|
||||||
|
|
||||||
|
|
||||||
describe('shape.appendNode', function() {
|
|
||||||
|
|
||||||
it('should execute', inject(function(elementRegistry, modeling) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
|
|
||||||
// when
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(targetShape).toBeDefined();
|
|
||||||
expect(target.$instanceOf('bpmn:Task')).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should execute', inject(function(elementRegistry, modeling) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
|
|
||||||
// when
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(targetShape).toBeDefined();
|
|
||||||
expect(target.$instanceOf('bpmn:ExclusiveGateway')).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should create DI', inject(function(elementRegistry, modeling) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
// when
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(target.di).toBeDefined();
|
|
||||||
expect(target.di.$parent).toBe(startEvent.di.$parent);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should add to parent (sub process)', inject(function(elementRegistry, modeling) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
// when
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(subProcess.get('flowElements')).toContain(target);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should add to parent (sub process)', inject(function(elementRegistry, modeling) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
// when
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(subProcess.get('flowElements')).toContain(target);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should add shape label', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
// when
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:EndEvent'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(targetShape.label).toBeDefined();
|
|
||||||
expect(elementRegistry.getById(targetShape.label.id)).toBeDefined();
|
|
||||||
|
|
||||||
expect(target.di.label).toBeDefined();
|
|
||||||
|
|
||||||
expect(target.di.label.bounds.x).toBe(targetShape.label.x);
|
|
||||||
expect(target.di.label.bounds.y).toBe(targetShape.label.y);
|
|
||||||
expect(target.di.label.bounds.width).toBe(targetShape.label.width);
|
|
||||||
expect(target.di.label.bounds.height).toBe(targetShape.label.height);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should add connection', inject(function(elementRegistry, modeling) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
// when
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
|
||||||
return e.sourceRef === startEvent && e.targetRef === target;
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).toBeDefined();
|
|
||||||
expect(connection.$instanceOf('bpmn:SequenceFlow')).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
describe('undo support', function() {
|
|
||||||
|
|
||||||
it('should undo add to parent', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(subProcess.get('flowElements')).not.toContain(target);
|
|
||||||
expect(subProcess.di.$parent.get('planeElement')).not.toContain(target.di);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should undo add shape label', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:EndEvent'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
|
||||||
return e.sourceRef === startEvent && e.targetRef === target;
|
|
||||||
});
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection.sourceRef).toBe(null);
|
|
||||||
expect(connection.targetRef).toBe(null);
|
|
||||||
expect(connection.$parent).toBe(null);
|
|
||||||
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
|
||||||
|
|
||||||
expect(targetShape.label).not.toBeDefined();
|
|
||||||
expect(elementRegistry.getById(target.id + '_label')).not.toBeDefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should undo add connection', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
|
||||||
return e.sourceRef === startEvent && e.targetRef === target;
|
|
||||||
});
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection.sourceRef).toBe(null);
|
|
||||||
expect(connection.targetRef).toBe(null);
|
|
||||||
|
|
||||||
expect(startEvent.get('outgoing')).not.toContain(connection);
|
|
||||||
expect(target.get('incoming')).not.toContain(connection);
|
|
||||||
|
|
||||||
expect(connection.$parent).toBe(null);
|
|
||||||
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
|
||||||
|
|
||||||
expect(elementRegistry.getById(targetShape.id)).not.toBeDefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should undo add connection label', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
|
||||||
return e.sourceRef === startEvent && e.targetRef === target;
|
|
||||||
});
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection.sourceRef).toBe(null);
|
|
||||||
expect(connection.targetRef).toBe(null);
|
|
||||||
expect(connection.$parent).toBe(null);
|
|
||||||
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
|
||||||
|
|
||||||
expect(elementRegistry.getById(connection.id + '_label')).not.toBeDefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should undo add to parent', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(subProcess.get('flowElements')).not.toContain(target);
|
|
||||||
expect(subProcess.di.$parent.get('planeElement')).not.toContain(target.di);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should redo appending multiple shapes', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape2 = modeling.appendFlowNode(targetShape, 'bpmn:UserTask');
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
commandStack.undo();
|
|
||||||
commandStack.redo();
|
|
||||||
commandStack.redo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
// expect redo to work on original target object
|
|
||||||
expect(targetShape.parent).toBe(subProcessShape);
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
commandStack.undo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(targetShape2.parent).toBe(null);
|
|
||||||
expect(elementRegistry.getById(targetShape2.id)).not.toBeDefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should redo add connection', inject(function(elementRegistry, modeling, commandStack) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
|
||||||
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
|
||||||
|
|
||||||
var startEvent = startEventShape.businessObject,
|
|
||||||
subProcess = subProcessShape.businessObject;
|
|
||||||
|
|
||||||
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
|
||||||
target = targetShape.businessObject;
|
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
|
||||||
return e.sourceRef === startEvent && e.targetRef === target;
|
|
||||||
});
|
|
||||||
|
|
||||||
// when
|
|
||||||
commandStack.undo();
|
|
||||||
commandStack.redo();
|
|
||||||
commandStack.undo();
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection.sourceRef).toBe(null);
|
|
||||||
expect(connection.targetRef).toBe(null);
|
|
||||||
expect(connection.$parent).toBe(null);
|
|
||||||
|
|
||||||
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
'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 - move shape', function() {
|
||||||
|
|
||||||
|
beforeEach(Matchers.add);
|
||||||
|
|
||||||
|
|
||||||
|
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
||||||
|
|
||||||
|
var testModules = [ drawModule, modelingModule ];
|
||||||
|
|
||||||
|
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
describe('shape handling', function() {
|
||||||
|
|
||||||
|
it('should execute', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1'),
|
||||||
|
startEvent = startEventShape.businessObject;
|
||||||
|
|
||||||
|
var oldPosition = {
|
||||||
|
x: startEventShape.x,
|
||||||
|
y: startEventShape.y
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.moveShape(startEventShape, { dx: 0, dy: 50 });
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(startEvent.di.bounds.x).toBe(oldPosition.x);
|
||||||
|
expect(startEvent.di.bounds.y).toBe(oldPosition.y + 50);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should execute on label', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var labelShape = elementRegistry.getById('StartEvent_1_label'),
|
||||||
|
startEvent = labelShape.businessObject;
|
||||||
|
|
||||||
|
var oldPosition = {
|
||||||
|
x: labelShape.x,
|
||||||
|
y: labelShape.y
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.moveShape(labelShape, { dx: 0, dy: 50 });
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(startEvent.di.label.bounds.x).toBe(oldPosition.x);
|
||||||
|
expect(startEvent.di.label.bounds.y).toBe(oldPosition.y + 50);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('undo support', function() {
|
||||||
|
|
||||||
|
it('should undo', inject(function(elementRegistry, commandStack, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1'),
|
||||||
|
startEvent = startEventShape.businessObject;
|
||||||
|
|
||||||
|
var oldPosition = {
|
||||||
|
x: startEventShape.x,
|
||||||
|
y: startEventShape.y
|
||||||
|
};
|
||||||
|
|
||||||
|
modeling.moveShape(startEventShape, { dx: 0, dy: 50 });
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(startEvent.di.bounds.x).toBe(oldPosition.x);
|
||||||
|
expect(startEvent.di.bounds.y).toBe(oldPosition.y);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo on label', inject(function(elementRegistry, commandStack, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var labelShape = elementRegistry.getById('StartEvent_1_label'),
|
||||||
|
startEvent = labelShape.businessObject;
|
||||||
|
|
||||||
|
var oldPosition = {
|
||||||
|
x: labelShape.x,
|
||||||
|
y: labelShape.y
|
||||||
|
};
|
||||||
|
|
||||||
|
modeling.moveShape(labelShape, { dx: 0, dy: 50 });
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(startEvent.di.label.bounds.x).toBe(oldPosition.x);
|
||||||
|
expect(startEvent.di.label.bounds.y).toBe(oldPosition.y);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue