diff --git a/lib/features/replace/BpmnReplace.js b/lib/features/replace/BpmnReplace.js
index 9ce5f02d..77ba0566 100644
--- a/lib/features/replace/BpmnReplace.js
+++ b/lib/features/replace/BpmnReplace.js
@@ -17,10 +17,6 @@ var is = require('../../util/ModelUtil').is,
getBusinessObject = require('../../util/ModelUtil').getBusinessObject,
isExpanded = require('../../util/DiUtil').isExpanded;
-var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
-
-var inherits = require('inherits');
-
/**
* A replace menu provider that gives users the controls to choose
* and replace BPMN elements with each other.
@@ -32,7 +28,9 @@ var inherits = require('inherits');
*/
function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modeling, eventBus) {
- CommandInterceptor.call(this, eventBus);
+ var self = this,
+ currentElement;
+
/**
* Prepares a new business object for the replacement element
@@ -94,51 +92,34 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
return newElement;
}
- function updateElementProperties(e) {
- var context = e.context;
- modeling.updateProperties(context.element, context.updatedProperties);
- }
+ function toggleLoopEntry(event, entry) {
+ var loopEntries = self.getLoopEntries(currentElement);
- this.postExecute([
- 'entries.update',
- ], updateElementProperties);
-
- var toggleEntries,
- toggledElement;
-
- function toggleMi(event, entry) {
-
- var loopCharacteristics,
- updatedEntries = [];
+ var loopCharacteristics;
if (entry.active) {
loopCharacteristics = undefined;
-
- updatedEntries.push({ id: entry.id, active: false });
} else {
- forEach(toggleEntries, function(action) {
+ forEach(loopEntries, function(action) {
var options = action.options;
if (entry.id === action.id) {
- updatedEntries.push({ id: entry.id, active: true });
-
loopCharacteristics = moddle.create(options.loopCharacteristics);
if (options.isSequential) {
loopCharacteristics.isSequential = options.isSequential;
}
- } else {
- updatedEntries.push({ id: action.id, active: false });
}
});
}
-
- popupMenu.updateHeaderEntries(updatedEntries, toggledElement, { loopCharacteristics: loopCharacteristics });
+ modeling.updateProperties(currentElement, { loopCharacteristics: loopCharacteristics });
}
- function getToggleOptions(element) {
+ function getLoopEntries(element) {
+
+ currentElement = element;
var businessObject = getBusinessObject(element),
loopCharacteristics = businessObject.loopCharacteristics;
@@ -153,14 +134,12 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
isParallel = loopCharacteristics.isSequential !== undefined && !loopCharacteristics.isSequential;
}
- toggledElement = element;
-
- toggleEntries = [
+ var loopEntries = [
{
id: 'toggle-parallel-mi',
className: 'icon-parallel-mi-marker',
active: isParallel,
- action: toggleMi,
+ action: toggleLoopEntry,
options: {
loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
isSequential: false
@@ -170,7 +149,7 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
id: 'toggle-sequential-mi',
className: 'icon-sequential-mi-marker',
active: isSequential,
- action: toggleMi,
+ action: toggleLoopEntry,
options: {
loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
isSequential: true
@@ -180,14 +159,35 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
id: 'toggle-loop',
className: 'icon-loop-marker',
active: isLoop,
- action: toggleMi,
+ action: toggleLoopEntry,
options: {
loopCharacteristics: 'bpmn:StandardLoopCharacteristics'
}
}
];
+ return loopEntries;
+ }
- return toggleEntries;
+
+ function getAdHocEntry(element) {
+ var businessObject = getBusinessObject(element);
+
+ var isAdHoc = is(businessObject, 'bpmn:AdHocSubProcess');
+
+ var adHocEntry = {
+ id: 'toggle-adhoc',
+ className: 'icon-ad-hoc-marker',
+ active: isAdHoc,
+ action: function(event, entry) {
+ if (isAdHoc) {
+ return replaceElement(element, { type: 'bpmn:SubProcess' });
+ } else {
+ return replaceElement(element, { type: 'bpmn:AdHocSubProcess' });
+ }
+ }
+ };
+
+ return adHocEntry;
}
@@ -229,12 +229,20 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
addEntries(subProcessExpandedReplace, filterEvents);
} else
+ if (is(businessObject, 'bpmn:AdHocSubProcess') && !isExpanded(businessObject)) {
+
+ addEntries(taskReplace, function(entry) {
+ return entry.target.type !== 'bpmn:SubProcess';
+ });
+ } else
+
if (is(businessObject, 'bpmn:FlowNode')) {
addEntries(taskReplace, function(entry) {
return entry.target.type !== businessObject.$type;
});
}
+
function filterEvents(entry) {
var target = entry.target;
@@ -248,6 +256,7 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
!(isEventDefinitionEqual && isEventTypeEqual);
}
+
function addEntries(entries, filterFun) {
// Filter selected type from the array
var filteredEntries = filter(entries, filterFun);
@@ -260,6 +269,7 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
});
}
+
function addMenuEntry(definition) {
return {
@@ -267,7 +277,7 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
className: definition.className,
id: definition.actionName,
action: function() {
- replaceElement(element, definition.target);
+ return replaceElement(element, definition.target);
}
};
}
@@ -282,32 +292,34 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin
*/
this.openChooser = function(position, element) {
var entries = this.getReplaceOptions(element),
- headerEntries;
+ headerEntries = [];
if (is(element, 'bpmn:Activity')) {
- headerEntries = this.getToggleOptions(element);
+ headerEntries = headerEntries.concat(this.getLoopEntries(element));
}
- popupMenu.open(
- {
- className: 'replace-menu',
- element: element,
- position: position,
- headerEntries: headerEntries,
- entries: entries
- }
- );
+ if (is(element, 'bpmn:SubProcess') && !is(element, 'bpmn:Transaction')) {
+ headerEntries.push(this.getAdHocEntry(element));
+ }
+
+ popupMenu.open({
+ className: 'replace-menu',
+ element: element,
+ position: position,
+ headerEntries: headerEntries,
+ entries: entries
+ });
};
this.getReplaceOptions = getReplaceOptions;
- this.getToggleOptions = getToggleOptions;
+ this.getLoopEntries = getLoopEntries;
+
+ this.getAdHocEntry = getAdHocEntry;
this.replaceElement = replaceElement;
}
-inherits(BpmnReplace, CommandInterceptor);
-
BpmnReplace.$inject = [ 'bpmnFactory', 'moddle', 'popupMenu', 'replace', 'selection', 'modeling', 'eventBus' ];
module.exports = BpmnReplace;
diff --git a/test/fixtures/bpmn/draw/activity-markers-simple.bpmn b/test/fixtures/bpmn/draw/activity-markers-simple.bpmn
index d3a75a16..444714c1 100644
--- a/test/fixtures/bpmn/draw/activity-markers-simple.bpmn
+++ b/test/fixtures/bpmn/draw/activity-markers-simple.bpmn
@@ -13,6 +13,7 @@
+
@@ -34,6 +35,9 @@
+
+
+
diff --git a/test/fixtures/bpmn/features/replace/01_replace.bpmn b/test/fixtures/bpmn/features/replace/01_replace.bpmn
index bd8746fe..711df8ec 100644
--- a/test/fixtures/bpmn/features/replace/01_replace.bpmn
+++ b/test/fixtures/bpmn/features/replace/01_replace.bpmn
@@ -28,73 +28,85 @@
+
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
diff --git a/test/spec/features/popup-menu/PopupMenuSpec.js b/test/spec/features/popup-menu/PopupMenuSpec.js
index 0373448b..5b43dcd2 100644
--- a/test/spec/features/popup-menu/PopupMenuSpec.js
+++ b/test/spec/features/popup-menu/PopupMenuSpec.js
@@ -33,305 +33,414 @@ describe('features/popup-menu', function() {
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
- afterEach(inject(function(popupMenu) {
- popupMenu.close();
- }));
- describe('active attribute', function(){
+ var openPopup = function(element, offset) {
+ offset = offset || 100;
- it('should be true for parallel marker', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('ParallelTask'),
- loopCharacteristics = task.businessObject.loopCharacteristics;
-
- // when
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- // then
- expect(is(loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
- expect(loopCharacteristics.isSequential).not.toBe(undefined);
- expect(loopCharacteristics.isSequential).toBe(false);
- expect(popupMenu._getEntry('toggle-parallel-mi').active).toBe(true);
- }));
+ TestHelper.getBpmnJS().invoke(function(bpmnReplace){
+ bpmnReplace.openChooser({ x: element.x + offset, y: element.y + offset }, element);
+ });
+ };
- it('should be true for sequential marker', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+ describe('toggle', function(){
- // given
- var task = elementRegistry.get('SequentialTask'),
- loopCharacteristics = task.businessObject.loopCharacteristics;
+ describe('active attribute', function(){
- // when
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
+ it('should be true for parallel marker', inject(function(popupMenu, bpmnReplace, elementRegistry) {
- // then
- expect(is(loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
- expect(loopCharacteristics.isSequential).toBe(true);
- expect(popupMenu._getEntry('toggle-sequential-mi').active).toBe(true);
- }));
+ // given
+ var task = elementRegistry.get('ParallelTask'),
+ loopCharacteristics = task.businessObject.loopCharacteristics;
+
+ // when
+ openPopup(task);
+
+ // then
+ expect(is(loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
+
+ expect(loopCharacteristics.isSequential).toBe(false);
+ expect(loopCharacteristics.isSequential).not.toBe(undefined);
+
+ expect(popupMenu._getEntry('toggle-parallel-mi').active).toBe(true);
+ }));
- it('should be true for loop marker', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+ it('should be true for sequential marker', inject(function(popupMenu, bpmnReplace, elementRegistry) {
- // given
- var task = elementRegistry.get('LoopTask'),
- loopCharacteristics = task.businessObject.loopCharacteristics;
+ // given
+ var task = elementRegistry.get('SequentialTask'),
+ loopCharacteristics = task.businessObject.loopCharacteristics;
- // when
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
+ // when
+ openPopup(task);
+
+ // then
+ expect(loopCharacteristics.isSequential).toBe(true);
+ expect(popupMenu._getEntry('toggle-sequential-mi').active).toBe(true);
+ expect(is(loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
+ }));
+
+
+ it('should be true for loop marker', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('LoopTask'),
+ loopCharacteristics = task.businessObject.loopCharacteristics;
+
+ // when
+ openPopup(task);
+
+ // then
+ expect(loopCharacteristics.isSequential).toBe(undefined);
+ expect(popupMenu._getEntry('toggle-loop').active).toBe(true);
+ expect(is(loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(false);
+ }));
+
+
+ it('should be true for ad hoc marker', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var AdHocSubProcess = elementRegistry.get('AdHocSubProcess');
+
+ // when
+ openPopup(AdHocSubProcess);
+
+ // then
+ expect(popupMenu._getEntry('toggle-adhoc').active).toBe(true);
+ }));
+
+ });
+
+ describe('exclusive toggle buttons', function(){
+
+ it('should not toggle non exclusive buttons off', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+ var subProcess = elementRegistry.get('AdHocSubProcess');
+
+ openPopup(subProcess);
+
+ var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(subProcess);
+
+ // then
+ var adHocEntry = queryEntry(popupMenu, 'toggle-adhoc');
+
+ expect(domClasses(adHocEntry).has('active')).toBe(true);
+ }));
+
+ });
+
+ describe('non exclusive toggle buttons', function(){
+
+ it('should not toggle exclusive buttons off',
+ inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var subProcess = elementRegistry.get('SubProcess');
+
+ // when
+
+ // toggle parallel on
+ openPopup(subProcess);
+
+ var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ popupMenu.trigger(Events.create(parallelEntry, { x: 0, y: 0 }));
+
+ // toggle ad hoc on
+ openPopup(subProcess);
+
+ var adHocEntry = queryEntry(popupMenu, 'toggle-adhoc');
+
+ var adHocSubProcess = popupMenu.trigger(Events.create(adHocEntry, { x: 0, y: 0 }));
+
+ openPopup(adHocSubProcess);
+
+ // then
+ parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
+ adHocEntry = queryEntry(popupMenu, 'toggle-adhoc');
+
+ expect(domClasses(parallelEntry).has('active')).toBe(true);
+ expect(domClasses(adHocEntry).has('active')).toBe(true);
+ }));
+
+ });
+
+ describe('parallel toggle button', function(){
+
+ it('should toggle parallel marker off',
+ inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('ParallelTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // then
+ expect(task.businessObject.loopCharacteristics).toBe(undefined);
+ expect(domClasses(parallelEntry).has('active')).toBe(false);
+ }));
+
+
+ it('should toggle parallel marker on', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('Task');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // then
+ expect(domClasses(parallelEntry).has('active')).toBe(true);
+ expect(task.businessObject.loopCharacteristics.isSequential).toBe(false);
+ expect(is(task.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
+ }));
+
+
+ it('should set sequential button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('SequentialTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // then
+ expect(domClasses(sequentialEntry).has('active')).toBe(false);
+ }));
+
+
+ it('should set loop button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('LoopTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var loopEntry = queryEntry(popupMenu, 'toggle-loop');
+
+ // then
+ expect(domClasses(loopEntry).has('active')).toBe(false);
+ }));
+
+ });
+
+ describe('sequential toggle button', function(){
+
+ it('should toggle sequential marker off', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('SequentialTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // then
+ expect(task.businessObject.loopCharacteristics).toBe(undefined);
+ expect(domClasses(sequentialEntry).has('active')).toBe(false);
+ }));
+
+
+ it('should toggle sequential marker on', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('Task');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // then
+ expect(domClasses(sequentialEntry).has('active')).toBe(true);
+ expect(task.businessObject.loopCharacteristics.isSequential).toBe(true);
+ expect(is(task.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
+ }));
+
+
+ it('should set loop button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('LoopTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var loopEntry = queryEntry(popupMenu, 'toggle-loop');
+
+ // then
+ expect(domClasses(loopEntry).has('active')).toBe(false);
+ }));
+
+
+ it('should set parallel button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('ParallelTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // then
+ expect(domClasses(parallelEntry).has('active')).toBe(false);
+ }));
+
+ });
+
+ describe('loop toggle button', function(){
+
+ it('should toggle loop marker off', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('LoopTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-loop');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var loopEntry = queryEntry(popupMenu, 'toggle-loop');
+
+ // then
+ expect(domClasses(loopEntry).has('active')).toBe(false);
+ expect(is(task.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(undefined);
+ }));
+
+
+ it('should toggle loop marker on', inject(function(popupMenu, bpmnReplace, elementRegistry){
+
+ // given
+ var task = elementRegistry.get('Task');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-loop');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var loopEntry = queryEntry(popupMenu, 'toggle-loop');
+
+ // then
+ expect(domClasses(loopEntry).has('active')).toBe(true);
+ expect(is(task.businessObject.loopCharacteristics, 'bpmn:StandardLoopCharacteristics')).toBe(true);
+ }));
+
+
+ it('should set sequential button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('SequentialTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-loop');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
+
+ // then
+ expect(domClasses(sequentialEntry).has('active')).toBe(false);
+ }));
+
+
+ it('should set parallel button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
+
+ // given
+ var task = elementRegistry.get('ParallelTask');
+
+ openPopup(task);
+
+ var entry = queryEntry(popupMenu, 'toggle-loop');
+
+ // when
+ popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+
+ openPopup(task);
+
+ var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
+
+ // then
+ expect(domClasses(parallelEntry).has('active')).toBe(false);
+ }));
+ });
- // then
- expect(is(loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(false);
- expect(loopCharacteristics.isSequential).toBe(undefined);
- expect(popupMenu._getEntry('toggle-loop').active).toBe(true);
- }));
});
-
- describe('parallel toggle button', function(){
-
- it('should toggle parallel marker off', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('ParallelTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // then
- expect(task.businessObject.loopCharacteristics).toBe(undefined);
- expect(domClasses(parallelEntry).has('active')).toBe(false);
- }));
-
-
- it('should toggle parallel marker on', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('Task');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // then
- expect(is(task.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
- expect(task.businessObject.loopCharacteristics.isSequential).toBe(false);
- expect(domClasses(parallelEntry).has('active')).toBe(true);
- }));
-
-
- it('should set sequential button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('SequentialTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // then
- expect(domClasses(sequentialEntry).has('active')).toBe(false);
- }));
-
-
- it('should set loop button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('LoopTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var loopEntry = queryEntry(popupMenu, 'toggle-loop');
-
- // then
- expect(domClasses(loopEntry).has('active')).toBe(false);
- }));
- });
-
-
- describe('sequential toggle button', function(){
-
- it('should toggle sequential marker off', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('SequentialTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // then
- expect(task.businessObject.loopCharacteristics).toBe(undefined);
- expect(domClasses(sequentialEntry).has('active')).toBe(false);
- }));
-
-
- it('should toggle sequential marker on', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('Task');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
- var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // then
- expect(is(task.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
- expect(task.businessObject.loopCharacteristics.isSequential).toBe(true);
- expect(domClasses(sequentialEntry).has('active')).toBe(true);
- }));
-
-
- it('should set loop button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('LoopTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var loopEntry = queryEntry(popupMenu, 'toggle-loop');
-
- // then
- expect(domClasses(loopEntry).has('active')).toBe(false);
- }));
-
-
- it('should set parallel button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('ParallelTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // then
- expect(domClasses(parallelEntry).has('active')).toBe(false);
- }));
- });
-
-
- describe('loop toggle button', function(){
-
- it('should toggle loop marker off', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('LoopTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-loop');
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var loopEntry = queryEntry(popupMenu, 'toggle-loop');
-
- // then
- expect(is(task.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(undefined);
- expect(domClasses(loopEntry).has('active')).toBe(false);
- }));
-
-
- it('should toggle loop marker on', inject(function(popupMenu, bpmnReplace, elementRegistry){
-
- // given
- var task = elementRegistry.get('Task');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-loop');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var loopEntry = queryEntry(popupMenu, 'toggle-loop');
-
- // then
- expect(is(task.businessObject.loopCharacteristics, 'bpmn:StandardLoopCharacteristics')).toBe(true);
- expect(domClasses(loopEntry).has('active')).toBe(true);
- }));
-
-
- it('should set sequential button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('SequentialTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-loop');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var sequentialEntry = queryEntry(popupMenu, 'toggle-sequential-mi');
-
- // then
- expect(domClasses(sequentialEntry).has('active')).toBe(false);
- }));
-
-
- it('should set parallel button inactive', inject(function(popupMenu, bpmnReplace, elementRegistry) {
-
- // given
- var task = elementRegistry.get('ParallelTask');
-
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
-
- var entry = queryEntry(popupMenu, 'toggle-loop');
-
- // when
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
-
- var parallelEntry = queryEntry(popupMenu, 'toggle-parallel-mi');
-
- // then
- expect(domClasses(parallelEntry).has('active')).toBe(false);
- }));
- });
-
-
describe('replacing', function() {
it('should retain the loop characteristics', inject(function(popupMenu, bpmnReplace, elementRegistry) {
@@ -339,21 +448,18 @@ describe('features/popup-menu', function() {
// given
var task = elementRegistry.get('SequentialTask');
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
+ openPopup(task);
var entry = queryEntry(popupMenu, 'replace-with-send-task');
// when
// replacing the task with a send task
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+ var sendTask = popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
// then
- // get the send task from the registry
- var sendTask = elementRegistry.filter(function(element, gfx) { return element.type === 'bpmn:SendTask';})[0];
-
expect(sendTask.businessObject.loopCharacteristics).toBeDefined();
- expect(is(sendTask.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
expect(sendTask.businessObject.loopCharacteristics.isSequential).toBe(true);
+ expect(is(sendTask.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
}));
@@ -363,24 +469,18 @@ describe('features/popup-menu', function() {
// given
var task = elementRegistry.get('SequentialTask');
- bpmnReplace.openChooser({ x: task.x + 100, y: task.y + 100 }, task);
+ openPopup(task);
var entry = queryEntry(popupMenu, 'replace-with-call-activity');
// when
// replacing the task with a call activity
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+ var callActivity = popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
// then
- // get the send task from the registry
- var callActivity = elementRegistry.filter(function(element, gfx) {
- return element.type === 'bpmn:CallActivity';
- })[0];
-
expect(callActivity.businessObject.loopCharacteristics).toBeDefined();
- expect(is(callActivity.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
expect(callActivity.businessObject.loopCharacteristics.isSequential).toBe(true);
-
+ expect(is(callActivity.businessObject.loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics')).toBe(true);
}));
@@ -390,22 +490,16 @@ describe('features/popup-menu', function() {
// given
var subProcess = elementRegistry.get('SubProcess');
- bpmnReplace.openChooser({ x: subProcess.x + 100, y: subProcess.y + 100 }, subProcess);
+ openPopup(subProcess);
var entry = queryEntry(popupMenu, 'replace-with-transaction');
// when
// replacing the expanded sub process with a transaction
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+ var transaction = popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
// then
- // get the morphed transacion from the registry
- var transaction = elementRegistry.filter(function(element, gfx) {
- return element.x === subProcess.x && element.y === subProcess.y;
- })[0];
-
expect(isExpanded(transaction)).toBe(isExpanded(subProcess));
-
}));
@@ -415,22 +509,16 @@ describe('features/popup-menu', function() {
// given
var transaction = elementRegistry.get('Transaction');
- bpmnReplace.openChooser({ x: transaction.x + 100, y: transaction.y + 100 }, transaction);
+ openPopup(transaction);
var entry = queryEntry(popupMenu, 'replace-with-subprocess');
// when
// replacing the expanded sub process with a transaction
- popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
+ var subProcess = popupMenu.trigger(Events.create(entry, { x: 0, y: 0 }));
// then
- // get the morphed transacion from the registry
- var subProcess = elementRegistry.filter(function(element, gfx) {
- return element.x === transaction.x && element.y === transaction.y;
- })[0];
-
expect(isExpanded(subProcess)).toBe(isExpanded(transaction));
-
}));
});
diff --git a/test/spec/features/replace/BpmnReplaceSpec.js b/test/spec/features/replace/BpmnReplaceSpec.js
index 71264daf..d57a6622 100644
--- a/test/spec/features/replace/BpmnReplaceSpec.js
+++ b/test/spec/features/replace/BpmnReplaceSpec.js
@@ -7,7 +7,8 @@ var TestHelper = require('../../../TestHelper');
var modelingModule = require('../../../../lib/features/modeling'),
replaceModule = require('../../../../lib/features/replace'),
coreModule = require('../../../../lib/core'),
- is = require('../../../../lib/util/ModelUtil').is;
+ is = require('../../../../lib/util/ModelUtil').is,
+ isExpanded = require('../../../../lib/util/DiUtil').isExpanded;
describe('features/replace', function() {
@@ -21,7 +22,7 @@ describe('features/replace', function() {
describe('should replace', function() {
- it('task', inject(function(elementRegistry, modeling, bpmnReplace) {
+ it('task', inject(function(elementRegistry, bpmnReplace) {
// given
var task = elementRegistry.get('Task_1');
@@ -40,7 +41,7 @@ describe('features/replace', function() {
}));
- it('gateway', inject(function(elementRegistry, modeling, bpmnReplace) {
+ it('gateway', inject(function(elementRegistry, bpmnReplace) {
// given
var gateway = elementRegistry.get('ExclusiveGateway_1');
@@ -111,8 +112,8 @@ describe('features/replace', function() {
var newElement = bpmnReplace.replaceElement(task, newElementData);
// then
- expect(newElement.x).toBe(346);
- expect(newElement.y).toBe(149);
+ expect(newElement.x).toBe(task.x);
+ expect(newElement.y).toBe(task.y);
}));
});
@@ -120,7 +121,8 @@ describe('features/replace', function() {
describe('selection', function() {
- it('should select after replace', inject(function(elementRegistry, selection, bpmnReplace) {
+ it('should select after replace',
+ inject(function(elementRegistry, selection, bpmnReplace) {
// given
var task = elementRegistry.get('Task_1');
@@ -140,7 +142,8 @@ describe('features/replace', function() {
describe('label', function() {
- it('should keep copy label', inject(function(elementRegistry, bpmnReplace) {
+ it('should keep copy label',
+ inject(function(elementRegistry, bpmnReplace) {
// given
var task = elementRegistry.get('Task_1');
@@ -161,7 +164,8 @@ describe('features/replace', function() {
describe('undo support', function() {
- it('should undo replace', inject(function(elementRegistry, modeling, bpmnReplace, commandStack) {
+ it('should undo replace',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var task = elementRegistry.get('Task_1');
@@ -183,7 +187,8 @@ describe('features/replace', function() {
}));
- it('should redo replace', inject(function(elementRegistry, modeling, bpmnReplace, commandStack, eventBus) {
+ it('should redo replace',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var task = elementRegistry.get('Task_1');
@@ -216,7 +221,8 @@ describe('features/replace', function() {
describe('connection handling', function() {
- it('should reconnect valid connections', inject(function(elementRegistry, modeling, bpmnReplace) {
+ it('should reconnect valid connections',
+ inject(function(elementRegistry, bpmnReplace) {
// given
var task = elementRegistry.get('Task_1');
@@ -241,7 +247,8 @@ describe('features/replace', function() {
}));
- it('should remove invalid incomming connections', inject(function(elementRegistry, modeling, bpmnReplace) {
+ it('should remove invalid incomming connections',
+ inject(function(elementRegistry, bpmnReplace) {
// given
var task = elementRegistry.get('StartEvent_1');
@@ -262,7 +269,8 @@ describe('features/replace', function() {
}));
- it('should remove invalid outgoing connections', inject(function(elementRegistry, modeling, bpmnReplace) {
+ it('should remove invalid outgoing connections',
+ inject(function(elementRegistry, bpmnReplace) {
// given
var task = elementRegistry.get('EndEvent_1');
@@ -285,7 +293,8 @@ describe('features/replace', function() {
describe('undo support', function() {
- it('should reconnect valid connections', inject(function(elementRegistry, modeling, bpmnReplace, commandStack) {
+ it('should reconnect valid connections',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var task = elementRegistry.get('Task_1');
@@ -313,8 +322,8 @@ describe('features/replace', function() {
}));
- it('should remove invalid incoming connections', inject(function(elementRegistry,
- modeling, bpmnReplace, commandStack) {
+ it('should remove invalid incoming connections',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var startEvent = elementRegistry.get('StartEvent_1');
@@ -340,8 +349,8 @@ describe('features/replace', function() {
}));
- it('should remove invalid outgoing connections', inject(function(elementRegistry,
- modeling, bpmnReplace, commandStack) {
+ it('should remove invalid outgoing connections',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var endEvent = elementRegistry.get('EndEvent_1');
@@ -371,7 +380,8 @@ describe('features/replace', function() {
describe('redo support', function() {
- it('should reconnect valid connections', inject(function(elementRegistry, modeling, bpmnReplace, commandStack) {
+ it('should reconnect valid connections',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var task = elementRegistry.get('Task_1');
@@ -398,8 +408,8 @@ describe('features/replace', function() {
}));
- it('should remove invalid incoming connections', inject(function(elementRegistry,
- modeling, bpmnReplace, commandStack) {
+ it('should remove invalid incoming connections',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var startEvent = elementRegistry.get('StartEvent_1');
@@ -422,8 +432,8 @@ describe('features/replace', function() {
}));
- it('should remove invalid outgoing connections', inject(function(elementRegistry,
- modeling, bpmnReplace, commandStack) {
+ it('should remove invalid outgoing connections',
+ inject(function(elementRegistry, bpmnReplace, commandStack) {
// given
var endEvent = elementRegistry.get('EndEvent_1');
@@ -449,7 +459,6 @@ describe('features/replace', function() {
});
-
describe('children handling', function() {
it('should update bpmn containment properly', inject(function(elementRegistry, modeling, bpmnReplace) {
@@ -485,4 +494,81 @@ describe('features/replace', function() {
});
+ describe('sub processes', function() {
+
+ it('should allow morphing expanded into expanded ad hoc',
+ inject(function(bpmnReplace, elementRegistry) {
+
+ // given
+ var element = elementRegistry.get('SubProcess_1');
+ var newElementData = {
+ type: 'bpmn:AdHocSubProcess'
+ };
+
+ // when
+ var newElement = bpmnReplace.replaceElement(element, newElementData);
+
+ // then
+ expect(is(newElement, 'bpmn:AdHocSubProcess')).toBe(true);
+ expect(isExpanded(newElement)).toBe(true);
+ }));
+
+
+ it('should allow morphing expanded ad hoc into expanded',
+ inject(function(bpmnReplace, elementRegistry) {
+
+ // given
+ var element = elementRegistry.get('AdHocSubProcessExpanded');
+ var newElementData = {
+ type: 'bpmn:SubProcess'
+ };
+
+ // when
+ var newElement = bpmnReplace.replaceElement(element, newElementData);
+
+ // then
+ expect(is(newElement, 'bpmn:SubProcess')).toBe(true);
+ expect(is(newElement, 'bpmn:AdHocSubProcess')).toBe(false);
+ expect(isExpanded(newElement)).toBe(true);
+ }));
+
+
+ it('should allow morphing collapsed into collapsed ad hoc',
+ inject(function(bpmnReplace, elementRegistry) {
+
+ // given
+ var element = elementRegistry.get('SubProcessCollapsed');
+ var newElementData = {
+ type: 'bpmn:AdHocSubProcess'
+ };
+
+ // when
+ var newElement = bpmnReplace.replaceElement(element, newElementData);
+
+ // then
+ expect(is(newElement, 'bpmn:AdHocSubProcess')).toBe(true);
+ expect(isExpanded(newElement)).not.toBe(true);
+ }));
+
+
+ it('should allow morphing collapsed ad hoc into collapsed',
+ inject(function(bpmnReplace, elementRegistry) {
+
+ // given
+ var element = elementRegistry.get('AdHocSubProcessCollapsed');
+ var newElementData = {
+ type: 'bpmn:SubProcess'
+ };
+
+ // when
+ var newElement = bpmnReplace.replaceElement(element, newElementData);
+
+ // then
+ expect(is(newElement, 'bpmn:SubProcess')).toBe(true);
+ expect(is(newElement, 'bpmn:AdHocSubProcess')).toBe(false);
+ expect(isExpanded(newElement)).not.toBe(true);
+ }));
+
+ });
+
});