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) {
|
||||
|
||||
return this.create('bpmndi:BPMNShape', _.extend({
|
||||
|
|
|
@ -33,6 +33,13 @@ function BpmnUpdater(eventBus, bpmnFactory) {
|
|||
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) {
|
||||
self.updateConnection(e.context.connection);
|
||||
}
|
||||
|
@ -79,6 +86,18 @@ BpmnUpdater.prototype.updateShapeParent = function(shape) {
|
|||
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) {
|
||||
|
||||
if (parentDi && !parentDi.$instanceOf('bpmndi:BPMNPlane')) {
|
||||
|
@ -158,6 +177,13 @@ BpmnUpdater.prototype.updateConnection = function(connection) {
|
|||
|
||||
/////// helpers /////////////////////////////////////////
|
||||
|
||||
BpmnUpdater.prototype._getLabel = function(di) {
|
||||
if (!di.label) {
|
||||
di.label = this._bpmnFactory.createDiLabel();
|
||||
}
|
||||
|
||||
return di.label;
|
||||
};
|
||||
|
||||
BpmnUpdater.prototype.pre = function(commands, callback) {
|
||||
this.on(commands, 'preExecute', callback);
|
||||
|
|
|
@ -7,7 +7,11 @@ var BaseModeling = require('diagram-js/lib/features/modeling/Modeling');
|
|||
var AppendShapeHandler = require('./cmd/AppendShapeHandler'),
|
||||
CreateShapeHandler = require('diagram-js/lib/features/modeling/cmd/CreateShapeHandler'),
|
||||
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) {
|
||||
commandStack.registerHandler('shape.appendShape', AppendShapeHandler);
|
||||
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('connection.create', CreateConnectionHandler);
|
||||
commandStack.registerHandler('connection.layout', LayoutConnectionHandler);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -10,5 +10,6 @@ module.exports = {
|
|||
elementFactory: [ 'type', require('./ElementFactory') ],
|
||||
modeling: [ 'type', require('./Modeling') ],
|
||||
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