feat(features/modeling): implement BPMN update for shape+label move

Related to #2
This commit is contained in:
Nico Rehwaldt 2014-07-30 16:07:43 +02:00
parent 9f68cb4cf7
commit bc61e6c3ed
7 changed files with 541 additions and 372 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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