diff --git a/lib/features/modeling/BpmnFactory.js b/lib/features/modeling/BpmnFactory.js
index 5a508126d5..af80a20820 100644
--- a/lib/features/modeling/BpmnFactory.js
+++ b/lib/features/modeling/BpmnFactory.js
@@ -32,7 +32,12 @@ BpmnFactory.prototype._needsId = function(element) {
'bpmndi:BPMNEdge',
'bpmndi:BPMNDiagram',
'bpmndi:BPMNPlane',
- 'bpmn:Property'
+ 'bpmn:Property',
+ 'bpmn:InputOutputSpecification',
+ 'bpmn:DataInput',
+ 'bpmn:InputSet',
+ 'bpmn:DataOutput',
+ 'bpmn:OutputSet'
]);
};
diff --git a/lib/features/modeling/behavior/DataInputAssociationBehavior.js b/lib/features/modeling/behavior/DataInputAssociationBehavior.js
index 59a251fe28..bc4bc5fc6c 100644
--- a/lib/features/modeling/behavior/DataInputAssociationBehavior.js
+++ b/lib/features/modeling/behavior/DataInputAssociationBehavior.js
@@ -8,24 +8,19 @@ import {
} from 'diagram-js/lib/util/Collections';
import {
- find
+ find,
+ forEach
} from 'min-dash';
import {
is
} from '../../../util/ModelUtil';
-var TARGET_REF_PLACEHOLDER_NAME = '__targetRef_placeholder';
-
/**
- * This behavior makes sure we always set a fake
- * DataInputAssociation#targetRef as demanded by the BPMN 2.0
- * XSD schema.
- *
- * The reference is set to a bpmn:Property{ name: '__targetRef_placeholder' }
- * which is created on the fly and cleaned up afterwards if not needed
- * anymore.
+ * This behavior makes sure a bpmn:DataInput is created and referenced when a
+ * bpmn:DataInputAssociation is created. It also makes sure the bpmn:DataInput and
+ * the reference are removed when a bpmn:InputAssociation is removed.
*
* @param {EventBus} eventBus
* @param {BpmnFactory} bpmnFactory
@@ -40,66 +35,121 @@ export default function DataInputAssociationBehavior(eventBus, bpmnFactory) {
'connection.delete',
'connection.move',
'connection.reconnectEnd'
- ], ifDataInputAssociation(fixTargetRef));
+ ], ifDataInputAssociation(updateTargetRef));
this.reverted([
'connection.create',
'connection.delete',
'connection.move',
'connection.reconnectEnd'
- ], ifDataInputAssociation(fixTargetRef));
+ ], ifDataInputAssociation(updateTargetRef));
+ /**
+ * Create and return bpmn:DataInput.
+ *
+ * Create bpmn:InputOutputSpecification, dataInputs and inputSets if not
+ * found.
+ *
+ * @param {ModdleElement} element - Element.
+ *
+ * @returns {ModdleElement}
+ */
+ function createDataInput(element) {
+ var ioSpecification = element.get('ioSpecification');
- function usesTargetRef(element, targetRef, removedConnection) {
+ var inputSet, outputSet;
- var inputAssociations = element.get('dataInputAssociations');
+ if (!ioSpecification) {
+ ioSpecification = bpmnFactory.create('bpmn:InputOutputSpecification', {
+ dataInputs: [],
+ inputSets: []
+ });
- return find(inputAssociations, function(association) {
- return association !== removedConnection &&
- association.targetRef === targetRef;
- });
- }
+ element.ioSpecification = ioSpecification;
- function getTargetRef(element, create) {
+ inputSet = bpmnFactory.create('bpmn:InputSet', {
+ dataInputRefs: [],
+ name: 'Inputs'
+ });
- var properties = element.get('properties');
+ inputSet.$parent = ioSpecification;
- var targetRefProp = find(properties, function(p) {
- return p.name === TARGET_REF_PLACEHOLDER_NAME;
- });
+ collectionAdd(ioSpecification.get('inputSets'), inputSet);
- if (!targetRefProp && create) {
- targetRefProp = bpmnFactory.create('bpmn:Property', {
- name: TARGET_REF_PLACEHOLDER_NAME
+ outputSet = bpmnFactory.create('bpmn:OutputSet', {
+ dataOutputRefs: [],
+ name: 'Outputs'
});
- collectionAdd(properties, targetRefProp);
+ outputSet.$parent = ioSpecification;
+
+ collectionAdd(ioSpecification.get('outputSets'), outputSet);
}
- return targetRefProp;
- }
+ var dataInput = bpmnFactory.create('bpmn:DataInput');
- function cleanupTargetRef(element, connection) {
+ dataInput.$parent = ioSpecification;
- var targetRefProp = getTargetRef(element);
+ if (!ioSpecification.dataInputs) {
+ ioSpecification.dataInputs = [];
+ }
+
+ collectionAdd(ioSpecification.get('dataInputs'), dataInput);
+
+ if (!ioSpecification.inputSets) {
+ inputSet = bpmnFactory.create('bpmn:InputSet', {
+ dataInputRefs: [],
+ name: 'Inputs'
+ });
+
+ inputSet.$parent = ioSpecification;
+
+ collectionAdd(ioSpecification.get('inputSets'), inputSet);
+ }
+
+ inputSet = ioSpecification.get('inputSets')[0];
+
+ collectionAdd(inputSet.dataInputRefs, dataInput);
+
+ return dataInput;
+ }
+
+ /**
+ * Remove bpmn:DataInput that is referenced by connection as targetRef from
+ * bpmn:InputOutputSpecification.
+ *
+ * @param {ModdleElement} element - Element.
+ * @param {ModdleElement} connection - Connection that references
+ * bpmn:DataInput.
+ */
+ function removeDataInput(element, connection) {
+ var dataInput = getDataInput(element, connection.targetRef);
- if (!targetRefProp) {
+ if (!dataInput) {
return;
}
- if (!usesTargetRef(element, targetRefProp, connection)) {
- collectionRemove(element.get('properties'), targetRefProp);
+ var ioSpecification = element.get('ioSpecification');
+
+ if (ioSpecification &&
+ ioSpecification.dataInputs &&
+ ioSpecification.inputSets) {
+
+ collectionRemove(ioSpecification.dataInputs, dataInput);
+
+ collectionRemove(ioSpecification.inputSets[0].dataInputRefs, dataInput);
+
+ cleanUpIoSpecification(element);
}
}
/**
- * Make sure targetRef is set to a valid property or
+ * Make sure targetRef is set to a valid bpmn:DataInput or
* `null` if the connection is detached.
*
- * @param {Event} event
+ * @param {Event} event - Event.
*/
- function fixTargetRef(event) {
-
+ function updateTargetRef(event) {
var context = event.context,
connection = context.connection,
connectionBo = connection.businessObject,
@@ -111,19 +161,20 @@ export default function DataInputAssociationBehavior(eventBus, bpmnFactory) {
oldTargetBo = oldTarget && oldTarget.businessObject;
var dataAssociation = connection.businessObject,
- targetRefProp;
+ dataInput;
if (oldTargetBo && oldTargetBo !== targetBo) {
- cleanupTargetRef(oldTargetBo, connectionBo);
+ removeDataInput(oldTargetBo, connectionBo);
}
if (newTargetBo && newTargetBo !== targetBo) {
- cleanupTargetRef(newTargetBo, connectionBo);
+ removeDataInput(newTargetBo, connectionBo);
}
if (targetBo) {
- targetRefProp = getTargetRef(targetBo, true);
- dataAssociation.targetRef = targetRefProp;
+ dataInput = createDataInput(targetBo, true);
+
+ dataAssociation.targetRef = dataInput;
} else {
dataAssociation.targetRef = null;
}
@@ -137,6 +188,7 @@ DataInputAssociationBehavior.$inject = [
inherits(DataInputAssociationBehavior, CommandInterceptor);
+// helpers //////////
/**
* Only call the given function when the event
@@ -146,7 +198,6 @@ inherits(DataInputAssociationBehavior, CommandInterceptor);
* @return {Function}
*/
function ifDataInputAssociation(fn) {
-
return function(event) {
var context = event.context,
connection = context.connection;
@@ -155,4 +206,59 @@ function ifDataInputAssociation(fn) {
return fn(event);
}
};
+}
+
+/**
+ * Get bpmn:DataInput that is is referenced by element as targetRef.
+ *
+ * @param {ModdleElement} element - Element.
+ * @param {ModdleElement} targetRef - Element that is targetRef.
+ *
+ * @returns {ModdleElement}
+ */
+export function getDataInput(element, targetRef) {
+ var ioSpecification = element.get('ioSpecification');
+
+ if (ioSpecification && ioSpecification.dataInputs) {
+ return find(ioSpecification.dataInputs, function(dataInput) {
+ return dataInput === targetRef;
+ });
+ }
+}
+
+/**
+ * Clean up and remove bpmn:InputOutputSpecification from an element if it's empty.
+ *
+ * @param {ModdleElement} element - Element.
+ */
+function cleanUpIoSpecification(element) {
+ var ioSpecification = element.get('ioSpecification');
+
+ var dataInputs,
+ dataOutputs,
+ inputSets,
+ outputSets;
+
+ if (ioSpecification) {
+ dataInputs = ioSpecification.dataInputs;
+ dataOutputs = ioSpecification.dataOutputs;
+ inputSets = ioSpecification.inputSets;
+ outputSets = ioSpecification.outputSets;
+
+ if (dataInputs && !dataInputs.length) {
+ delete ioSpecification.dataInputs;
+ }
+
+ if (dataOutputs && !dataOutputs.length) {
+ delete ioSpecification.dataOutputs;
+ }
+
+ if ((!dataInputs || !dataInputs.length) &&
+ (!dataOutputs || !dataOutputs.length) &&
+ !inputSets[0].dataInputRefs.length &&
+ !outputSets[0].dataOutputRefs.length) {
+
+ delete element.ioSpecification;
+ }
+ }
}
\ No newline at end of file
diff --git a/lib/features/modeling/behavior/DataOutputAssociationBehavior.js b/lib/features/modeling/behavior/DataOutputAssociationBehavior.js
new file mode 100644
index 0000000000..8b477dd4d7
--- /dev/null
+++ b/lib/features/modeling/behavior/DataOutputAssociationBehavior.js
@@ -0,0 +1,265 @@
+import inherits from 'inherits';
+
+import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
+
+import {
+ add as collectionAdd,
+ remove as collectionRemove
+} from 'diagram-js/lib/util/Collections';
+
+import {
+ find,
+ forEach
+} from 'min-dash';
+
+import {
+ is
+} from '../../../util/ModelUtil';
+
+
+/**
+ * This behavior makes sure a bpmn:DataOutput is created and referenced when a
+ * bpmn:DataOutputAssociation is created. It also makes sure the bpmn:DataOutput and
+ * the reference are removed when a bpmn:OutputAssociation is removed.
+ *
+ * @param {EventBus} eventBus
+ * @param {BpmnFactory} bpmnFactory
+ */
+export default function DataOutputAssociationBehavior(eventBus, bpmnFactory) {
+
+ CommandInterceptor.call(this, eventBus);
+
+
+ this.executed([
+ 'connection.create',
+ 'connection.delete',
+ 'connection.move',
+ 'connection.reconnectStart'
+ ], ifDataOutputAssociation(updateSoureRef));
+
+ this.reverted([
+ 'connection.create',
+ 'connection.delete',
+ 'connection.move',
+ 'connection.reconnectStart'
+ ], ifDataOutputAssociation(updateSoureRef));
+
+ /**
+ * Create and return bpmn:DataOutput.
+ *
+ * Create bpmn:InputOutputSpecification, dataOutputs and outputSets if not
+ * found.
+ *
+ * @param {ModdleElement} element - Element.
+ *
+ * @returns {ModdleElement}
+ */
+ function createDataOutput(element) {
+ var ioSpecification = element.get('ioSpecification');
+
+ var inputSet, outputSet;
+
+ if (!ioSpecification) {
+ ioSpecification = bpmnFactory.create('bpmn:InputOutputSpecification', {
+ dataOutputs: [],
+ outputSets: []
+ });
+
+ element.ioSpecification = ioSpecification;
+
+ inputSet = bpmnFactory.create('bpmn:InputSet', {
+ dataInputRefs: [],
+ name: 'Inputs'
+ });
+
+ inputSet.$parent = ioSpecification;
+
+ collectionAdd(ioSpecification.get('inputSets'), inputSet);
+
+ outputSet = bpmnFactory.create('bpmn:OutputSet', {
+ dataOutputRefs: [],
+ name: 'Outputs'
+ });
+
+ outputSet.$parent = ioSpecification;
+
+ collectionAdd(ioSpecification.get('outputSets'), outputSet);
+ }
+
+ var dataOutput = bpmnFactory.create('bpmn:DataOutput');
+
+ dataOutput.$parent = ioSpecification;
+
+ if (!ioSpecification.dataOutputs) {
+ ioSpecification.dataOutputs = [];
+ }
+
+ collectionAdd(ioSpecification.get('dataOutputs'), dataOutput);
+
+ if (!ioSpecification.outputSets) {
+ outputSet = bpmnFactory.create('bpmn:OutputSet', {
+ dataOutputRefs: [],
+ name: 'Outputs'
+ });
+
+ outputSet.$parent = ioSpecification;
+
+ collectionAdd(ioSpecification.get('outputSets'), outputSet);
+ }
+
+ outputSet = ioSpecification.get('outputSets')[0];
+
+ collectionAdd(outputSet.dataOutputRefs, dataOutput);
+
+ return dataOutput;
+ }
+
+ /**
+ * Remove bpmn:DataOutput that is referenced by connection as sourceRef from
+ * bpmn:InputOutputSpecification.
+ *
+ * @param {ModdleElement} element - Element.
+ * @param {ModdleElement} connection - Connection that references
+ * bpmn:DataOutput.
+ */
+ function removeDataOutput(element, connection) {
+ var dataOutput = getDataOutput(element, connection.get('sourceRef')[0]);
+
+ if (!dataOutput) {
+ return;
+ }
+
+ var ioSpecification = element.get('ioSpecification');
+
+ if (ioSpecification &&
+ ioSpecification.dataOutputs &&
+ ioSpecification.outputSets) {
+
+ collectionRemove(ioSpecification.dataOutputs, dataOutput);
+
+ collectionRemove(ioSpecification.outputSets[0].dataOutputRefs, dataOutput);
+
+ cleanUpIoSpecification(element);
+ }
+ }
+
+ /**
+ * Make sure sourceRef is set to a valid bpmn:DataOutput or
+ * `null` if the connection is detached.
+ *
+ * @param {Event} event - Event.
+ */
+ function updateSoureRef(event) {
+ var context = event.context,
+ connection = context.connection,
+ connectionBo = connection.businessObject,
+ source = connection.source,
+ sourceBo = source && source.businessObject,
+ newsource = context.newsource,
+ newsourceBo = newsource && newsource.businessObject,
+ oldsource = context.oldsource || context.source,
+ oldsourceBo = oldsource && oldsource.businessObject;
+
+ var dataAssociation = connection.businessObject,
+ dataOutput;
+
+ if (oldsourceBo && oldsourceBo !== sourceBo) {
+ removeDataOutput(oldsourceBo, connectionBo);
+ }
+
+ if (newsourceBo && newsourceBo !== sourceBo) {
+ removeDataOutput(newsourceBo, connectionBo);
+ }
+
+ if (sourceBo) {
+ dataOutput = createDataOutput(sourceBo, true);
+
+ // sourceRef is isMany
+ dataAssociation.get('sourceRef')[0] = dataOutput;
+ } else {
+ dataAssociation.sourceRef = null;
+ }
+ }
+}
+
+DataOutputAssociationBehavior.$inject = [
+ 'eventBus',
+ 'bpmnFactory'
+];
+
+inherits(DataOutputAssociationBehavior, CommandInterceptor);
+
+// helpers //////////
+
+/**
+ * Only call the given function when the event
+ * touches a bpmn:DataOutputAssociation.
+ *
+ * @param {Function} fn
+ * @return {Function}
+ */
+function ifDataOutputAssociation(fn) {
+ return function(event) {
+ var context = event.context,
+ connection = context.connection;
+
+ if (is(connection, 'bpmn:DataOutputAssociation')) {
+ return fn(event);
+ }
+ };
+}
+
+/**
+ * Get bpmn:DataOutput that is is referenced by element as sourceRef.
+ *
+ * @param {ModdleElement} element - Element.
+ * @param {ModdleElement} sourceRef - Element that is sourceRef.
+ *
+ * @returns {ModdleElement}
+ */
+export function getDataOutput(element, sourceRef) {
+ var ioSpecification = element.get('ioSpecification');
+
+ if (ioSpecification && ioSpecification.dataOutputs) {
+ return find(ioSpecification.dataOutputs, function(dataOutput) {
+ return dataOutput === sourceRef;
+ });
+ }
+}
+
+/**
+ * Clean up and remove bpmn:InputOutputSpecification from an element if it's empty.
+ *
+ * @param {ModdleElement} element - Element.
+ */
+function cleanUpIoSpecification(element) {
+ var ioSpecification = element.get('ioSpecification');
+
+ var dataInputs,
+ dataOutputs,
+ inputSets,
+ outputSets;
+
+ if (ioSpecification) {
+ dataInputs = ioSpecification.dataInputs;
+ dataOutputs = ioSpecification.dataOutputs;
+ inputSets = ioSpecification.inputSets;
+ outputSets = ioSpecification.outputSets;
+
+ if (dataInputs && !dataInputs.length) {
+ delete ioSpecification.dataInputs;
+ }
+
+ if (dataOutputs && !dataOutputs.length) {
+ delete ioSpecification.dataOutputs;
+ }
+
+ if ((!dataInputs || !dataInputs.length) &&
+ (!dataOutputs || !dataOutputs.length) &&
+ !inputSets[0].dataInputRefs.length &&
+ !outputSets[0].dataOutputRefs.length) {
+
+ delete element.ioSpecification;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/features/modeling/behavior/index.js b/lib/features/modeling/behavior/index.js
index 98f0510290..4e9621f542 100644
--- a/lib/features/modeling/behavior/index.js
+++ b/lib/features/modeling/behavior/index.js
@@ -6,6 +6,7 @@ import CreateBoundaryEventBehavior from './CreateBoundaryEventBehavior';
import CreateDataObjectBehavior from './CreateDataObjectBehavior';
import CreateParticipantBehavior from './CreateParticipantBehavior';
import DataInputAssociationBehavior from './DataInputAssociationBehavior';
+import DataOutputAssociationBehavior from './DataOutputAssociationBehavior';
import DataStoreBehavior from './DataStoreBehavior';
import DeleteLaneBehavior from './DeleteLaneBehavior';
import DropOnFlowBehavior from './DropOnFlowBehavior';
@@ -33,6 +34,7 @@ export default {
'dataStoreBehavior',
'createParticipantBehavior',
'dataInputAssociationBehavior',
+ 'dataOutputAssociationBehavior',
'deleteLaneBehavior',
'dropOnFlowBehavior',
'importDockingFix',
@@ -56,6 +58,7 @@ export default {
createDataObjectBehavior: [ 'type', CreateDataObjectBehavior ],
createParticipantBehavior: [ 'type', CreateParticipantBehavior ],
dataInputAssociationBehavior: [ 'type', DataInputAssociationBehavior ],
+ dataOutputAssociationBehavior: [ 'type', DataOutputAssociationBehavior ],
dataStoreBehavior: [ 'type', DataStoreBehavior ],
deleteLaneBehavior: [ 'type', DeleteLaneBehavior ],
dropOnFlowBehavior: [ 'type', DropOnFlowBehavior ],
diff --git a/test/spec/features/modeling/behavior/DataAssociationBehavior.bpmn b/test/spec/features/modeling/behavior/DataAssociationBehavior.bpmn
new file mode 100644
index 0000000000..18b262fee5
--- /dev/null
+++ b/test/spec/features/modeling/behavior/DataAssociationBehavior.bpmn
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/spec/features/modeling/behavior/DataAssociationBehaviorSpec.js b/test/spec/features/modeling/behavior/DataAssociationBehaviorSpec.js
new file mode 100644
index 0000000000..7c68a081af
--- /dev/null
+++ b/test/spec/features/modeling/behavior/DataAssociationBehaviorSpec.js
@@ -0,0 +1,129 @@
+import {
+ bootstrapModeler,
+ inject
+} from 'test/TestHelper';
+
+import modelingModule from 'lib/features/modeling';
+
+import {
+ getDataInput
+} from 'lib/features/modeling/behavior/DataInputAssociationBehavior';
+
+import {
+ getDataOutput
+} from 'lib/features/modeling/behavior/DataOutputAssociationBehavior';
+
+
+describe('modeling/behavior - DataInputAssociationBehavior and DataOutputAssociationBehavior integration', function() {
+
+ var diagramXML = require('./DataAssociationBehavior.bpmn');
+
+ beforeEach(bootstrapModeler(diagramXML, { modules: modelingModule }));
+
+
+ it('should add bpmn:DataInput and bpmn:DataOutput on connect -> connect', inject(function(elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataInputAssociation = modeling.connect(dataObject1, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ // when
+ var dataOutputAssociation = modeling.connect(task, dataObject2, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // then
+ var dataInputAssociationBo = dataInputAssociation.businessObject,
+ dataOutputAssociationBo = dataOutputAssociation.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+
+ expect(taskBo.ioSpecification.dataInputs).to.have.length(1);
+ expect(taskBo.ioSpecification.inputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.inputSets[0].dataInputRefs).to.have.length(1);
+
+ expect(taskBo.ioSpecification.dataOutputs).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets[0].dataOutputRefs).to.have.length(1);
+
+ expect(dataInputAssociationBo.targetRef).to.exist;
+ expect(dataInputAssociationBo.targetRef).to.eql(getDataInput(taskBo, dataInputAssociationBo.targetRef));
+
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.exist;
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.eql(getDataOutput(taskBo, dataOutputAssociationBo.get('sourceRef')[0]));
+ }));
+
+
+ it('should remove bpmn:DataOutput on connect -> undo', inject(function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataInputAssociation = modeling.connect(dataObject1, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ modeling.connect(task, dataObject2, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ commandStack.undo();
+
+ // then
+ var dataInputAssociationBo = dataInputAssociation.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+
+ expect(taskBo.ioSpecification.dataInputs).to.have.length(1);
+ expect(taskBo.ioSpecification.dataOutputs).to.not.exist;
+
+ expect(taskBo.ioSpecification.inputSets).to.exist;
+ expect(taskBo.ioSpecification.inputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.inputSets[0].dataInputRefs).to.have.length(1);
+
+ expect(taskBo.ioSpecification.outputSets).to.exist;
+ expect(taskBo.ioSpecification.outputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets[0].dataOutputRefs).to.have.length(0);
+
+ expect(dataInputAssociationBo.targetRef).to.exist;
+ expect(dataInputAssociationBo.targetRef).to.eql(getDataInput(taskBo, dataInputAssociationBo.targetRef));
+ }));
+
+
+ it('should remove bpmn:DataInput and bpmn:DataOutput on connect -> connect -> undo -> undo', inject(
+ function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ modeling.connect(dataObject1, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ modeling.connect(task, dataObject2, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ commandStack.undo();
+ commandStack.undo();
+
+ // then
+ expect(taskBo.ioSpecification).not.to.exist;
+ }
+ ));
+
+});
\ No newline at end of file
diff --git a/test/spec/features/modeling/behavior/DataInputAssociationBehavior.bpmn b/test/spec/features/modeling/behavior/DataInputAssociationBehavior.bpmn
deleted file mode 100644
index 7e21cd1eb3..0000000000
--- a/test/spec/features/modeling/behavior/DataInputAssociationBehavior.bpmn
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
- DataObjectReference
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/spec/features/modeling/behavior/DataInputAssociationBehaviorSpec.js b/test/spec/features/modeling/behavior/DataInputAssociationBehaviorSpec.js
index 859e1dedc0..05d98929c2 100644
--- a/test/spec/features/modeling/behavior/DataInputAssociationBehaviorSpec.js
+++ b/test/spec/features/modeling/behavior/DataInputAssociationBehaviorSpec.js
@@ -3,146 +3,256 @@ import {
inject
} from 'test/TestHelper';
-import {
- find
-} from 'min-dash';
-
import modelingModule from 'lib/features/modeling';
+import {
+ getDataInput
+} from 'lib/features/modeling/behavior/DataInputAssociationBehavior';
+
-describe('modeling/behavior - fix DataInputAssociation#targetRef', function() {
+describe('modeling/behavior - DataInputAssociationBehavior', function() {
- var diagramXML = require('./DataInputAssociationBehavior.bpmn');
+ var diagramXML = require('./DataAssociationBehavior.bpmn');
beforeEach(bootstrapModeler(diagramXML, { modules: modelingModule }));
- it('should add on connect', inject(function(modeling, elementRegistry) {
+ it('should add bpmn:DataInput on connect', inject(function(elementRegistry, modeling) {
// given
- var dataObjectShape = elementRegistry.get('DataObjectReference'),
- taskShape = elementRegistry.get('Task_B');
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
// when
- var newConnection = modeling.connect(dataObjectShape, taskShape, {
+ var dataInputAssociation = modeling.connect(dataObject, task, {
type: 'bpmn:DataInputAssociation'
});
- var dataInputAssociation = newConnection.businessObject;
-
// then
- expect(dataInputAssociation.targetRef).to.exist;
- expect(dataInputAssociation.targetRef).to.eql(getTargetRefProp(taskShape));
+ var dataInputAssociationBo = dataInputAssociation.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(taskBo.ioSpecification.inputSets).to.exist;
+ expect(taskBo.ioSpecification.inputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets).to.exist;
+ expect(taskBo.ioSpecification.outputSets).to.have.length(1);
+
+ expect(dataInputAssociationBo.targetRef).to.exist;
+ expect(dataInputAssociationBo.targetRef).to.eql(getDataInput(taskBo, dataInputAssociationBo.targetRef));
}));
- it('should remove on connect / undo', inject(function(modeling, elementRegistry, commandStack) {
+ it('should remove bpmn:DataInput on connect -> undo', inject(function(commandStack, elementRegistry, modeling) {
// given
- var dataObjectShape = elementRegistry.get('DataObjectReference'),
- taskShape = elementRegistry.get('Task_B');
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
- var newConnection = modeling.connect(dataObjectShape, taskShape, {
+ modeling.connect(dataObject, task, {
type: 'bpmn:DataInputAssociation'
});
- var dataInputAssociation = newConnection.businessObject;
-
// when
commandStack.undo();
// then
- expect(dataInputAssociation.targetRef).not.to.exist;
- expect(getTargetRefProp(taskShape)).not.to.exist;
+ expect(taskBo.ioSpecification).not.to.exist;
}));
- it('should update on reconnectEnd', inject(function(modeling, elementRegistry) {
+ it('should update bpmn:DataInput on reconnectEnd', inject(function(elementRegistry, modeling) {
// given
- var oldTarget = elementRegistry.get('Task_A'),
- connection = elementRegistry.get('DataInputAssociation'),
- dataInputAssociation = connection.businessObject,
- newTarget = elementRegistry.get('Task_B');
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task1 = elementRegistry.get('Task_1'),
+ task1Bo = task1.businessObject,
+ task2 = elementRegistry.get('Task_2'),
+ task2Bo = task2.businessObject;
+
+ var dataInputAssociation = modeling.connect(dataObject, task1, {
+ type: 'bpmn:DataInputAssociation'
+ });
// when
- modeling.reconnectEnd(connection, newTarget, { x: newTarget.x, y: newTarget.y });
+ modeling.reconnectEnd(dataInputAssociation, task2, { x: task2.x, y: task2.y });
// then
- expect(getTargetRefProp(oldTarget)).not.to.exist;
+ var dataInputAssociationBo = dataInputAssociation.businessObject;
+
+ expect(getDataInput(task1Bo, dataInputAssociationBo.targetRef)).not.to.exist;
- expect(dataInputAssociation.targetRef).to.exist;
- expect(dataInputAssociation.targetRef).to.eql(getTargetRefProp(newTarget));
+ expect(getDataInput(task2Bo, dataInputAssociationBo.targetRef)).to.exist;
+ expect(dataInputAssociationBo.targetRef).to.eql(getDataInput(task2Bo, dataInputAssociationBo.targetRef));
}));
- it('should update on reconnectEnd / undo', inject(function(modeling, elementRegistry, commandStack) {
+ it('should update bpmn:DataInput on reconnectEnd -> undo', inject(function(commandStack, elementRegistry, modeling) {
// given
- var oldTarget = elementRegistry.get('Task_A'),
- connection = elementRegistry.get('DataInputAssociation'),
- dataInputAssociation = connection.businessObject,
- newTarget = elementRegistry.get('Task_B');
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task1 = elementRegistry.get('Task_1'),
+ task1Bo = task1.businessObject,
+ task2 = elementRegistry.get('Task_2'),
+ task2Bo = task2.businessObject;
- modeling.reconnectEnd(connection, newTarget, { x: newTarget.x, y: newTarget.y });
+ var dataInputAssociation = modeling.connect(dataObject, task1, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ modeling.reconnectEnd(dataInputAssociation, task2, { x: task2.x, y: task2.y });
// when
commandStack.undo();
// then
- expect(getTargetRefProp(newTarget)).not.to.exist;
+ var dataInputAssociationBo = dataInputAssociation.businessObject;
- expect(dataInputAssociation.targetRef).to.exist;
- expect(dataInputAssociation.targetRef).to.eql(getTargetRefProp(oldTarget));
+ expect(getDataInput(task1Bo, dataInputAssociationBo.targetRef)).to.exist;
+ expect(dataInputAssociationBo.targetRef).to.eql(getDataInput(task1Bo, dataInputAssociationBo.targetRef));
+
+ expect(getDataInput(task2Bo, dataInputAssociationBo.targetRef)).not.to.exist;
}));
- it('should unset on remove', inject(function(modeling, elementRegistry) {
+ it('should remove bpmn:DataInput on remove', inject(function(elementRegistry, modeling) {
// given
- var oldTarget = elementRegistry.get('Task_A'),
- connection = elementRegistry.get('DataInputAssociation'),
- dataInputAssociation = connection.businessObject;
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataInputAssociation = modeling.connect(dataObject, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
// when
- modeling.removeElements([ connection ]);
+ modeling.removeElements([ dataInputAssociation ]);
// then
- expect(getTargetRefProp(oldTarget)).not.to.exist;
-
- expect(dataInputAssociation.targetRef).not.to.exist;
+ expect(taskBo.ioSpecification).not.to.exist;
}));
- it('should unset on remove / undo', inject(function(modeling, elementRegistry, commandStack) {
+ it('should add bpmn:DataInput on remove -> undo', inject(function(commandStack, elementRegistry, modeling) {
// given
- var oldTarget = elementRegistry.get('Task_A'),
- connection = elementRegistry.get('DataInputAssociation'),
- dataInputAssociation = connection.businessObject;
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataInputAssociation = modeling.connect(dataObject, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
- modeling.removeElements([ connection ]);
+ modeling.removeElements([ dataInputAssociation ]);
// when
commandStack.undo();
// then
- expect(dataInputAssociation.targetRef).to.exist;
- expect(dataInputAssociation.targetRef).to.eql(getTargetRefProp(oldTarget));
+ var dataInputAssociationBo = dataInputAssociation.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(dataInputAssociationBo.targetRef).to.exist;
+ expect(dataInputAssociationBo.targetRef).to.eql(getDataInput(taskBo, dataInputAssociationBo.targetRef));
}));
-});
+ describe('multiple bpmn:DataInput elements', function() {
+
+ it('should add second bpmn:DataInput on connect', inject(function(elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataInputAssociation1 = modeling.connect(dataObject1, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ // when
+ var dataInputAssociation2 = modeling.connect(dataObject2, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ // then
+ var dataInputAssociation1Bo = dataInputAssociation1.businessObject,
+ dataInputAssociation2Bo = dataInputAssociation2.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(taskBo.ioSpecification.dataInputs).to.have.length(2);
+ expect(taskBo.ioSpecification.inputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.inputSets[0].dataInputRefs).to.have.length(2);
+
+ expect(dataInputAssociation1Bo.targetRef).to.exist;
+ expect(dataInputAssociation1Bo.targetRef).to.eql(getDataInput(taskBo, dataInputAssociation1Bo.targetRef));
+
+ expect(dataInputAssociation2Bo.targetRef).to.exist;
+ expect(dataInputAssociation2Bo.targetRef).to.eql(getDataInput(taskBo, dataInputAssociation2Bo.targetRef));
+ }));
+
+
+ it('should remove second bpmn:DataInput on connect -> undo', inject(function(commandStack, elementRegistry, modeling) {
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
-function getTargetRefProp(element) {
+ var dataInputAssociation1 = modeling.connect(dataObject1, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
- expect(element).to.exist;
+ modeling.connect(dataObject2, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
- var properties = element.businessObject.get('properties');
+ // when
+ commandStack.undo();
+
+ // then
+ var dataInputAssociation1Bo = dataInputAssociation1.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(taskBo.ioSpecification.dataInputs).to.have.length(1);
+ expect(taskBo.ioSpecification.inputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.inputSets[0].dataInputRefs).to.have.length(1);
+
+ expect(dataInputAssociation1Bo.targetRef).to.exist;
+ expect(dataInputAssociation1Bo.targetRef).to.eql(getDataInput(taskBo, dataInputAssociation1Bo.targetRef));
+ }));
+
+
+ it('should remove all bpmn:DataInput elements on connect -> connect -> undo -> undo', inject(function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ modeling.connect(dataObject1, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ modeling.connect(dataObject2, task, {
+ type: 'bpmn:DataInputAssociation'
+ });
+
+ // when
+ commandStack.undo();
+ commandStack.undo();
+
+ // then
+ expect(taskBo.ioSpecification).not.to.exist;
+ }));
- return find(properties, function(p) {
- return p.name === '__targetRef_placeholder';
});
-}
\ No newline at end of file
+
+});
\ No newline at end of file
diff --git a/test/spec/features/modeling/behavior/DataOutputAssociationBehaviorSpec.js b/test/spec/features/modeling/behavior/DataOutputAssociationBehaviorSpec.js
new file mode 100644
index 0000000000..8fc1f0a87f
--- /dev/null
+++ b/test/spec/features/modeling/behavior/DataOutputAssociationBehaviorSpec.js
@@ -0,0 +1,258 @@
+import {
+ bootstrapModeler,
+ inject
+} from 'test/TestHelper';
+
+import modelingModule from 'lib/features/modeling';
+
+import {
+ getDataOutput
+} from 'lib/features/modeling/behavior/DataOutputAssociationBehavior';
+
+
+describe('modeling/behavior - DataOutputAssociationBehavior', function() {
+
+ var diagramXML = require('./DataAssociationBehavior.bpmn');
+
+ beforeEach(bootstrapModeler(diagramXML, { modules: modelingModule }));
+
+
+ it('should add bpmn:DataOutput on connect', inject(function(elementRegistry, modeling) {
+
+ // given
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+
+ // when
+ var dataOutputAssociation = modeling.connect(task, dataObject, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // then
+ var dataOutputAssociationBo = dataOutputAssociation.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(taskBo.ioSpecification.inputSets).to.exist;
+ expect(taskBo.ioSpecification.inputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets).to.exist;
+ expect(taskBo.ioSpecification.outputSets).to.have.length(1);
+
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.exist;
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.eql(getDataOutput(taskBo, dataOutputAssociationBo.get('sourceRef')[0]));
+ }));
+
+
+ it('should remove bpmn:DataOutput on connect -> undo', inject(function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ modeling.connect(task, dataObject, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ commandStack.undo();
+
+ // then
+ expect(taskBo.ioSpecification).not.to.exist;
+ }));
+
+
+ it('should update bpmn:DataOutput on reconnectStart', inject(function(elementRegistry, modeling) {
+
+ // given
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task1 = elementRegistry.get('Task_1'),
+ task1Bo = task1.businessObject,
+ task2 = elementRegistry.get('Task_2'),
+ task2Bo = task2.businessObject;
+
+ var dataOutputAssociation = modeling.connect(task1, dataObject, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ modeling.reconnectStart(dataOutputAssociation, task2, { x: task2.x, y: task2.y });
+
+ // then
+ var dataOutputAssociationBo = dataOutputAssociation.businessObject;
+
+ expect(getDataOutput(task1Bo, dataOutputAssociationBo.get('sourceRef')[0])).not.to.exist;
+
+ expect(getDataOutput(task2Bo, dataOutputAssociationBo.get('sourceRef')[0])).to.exist;
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.eql(getDataOutput(task2Bo, dataOutputAssociationBo.get('sourceRef')[0]));
+ }));
+
+
+ it('should update bpmn:DataOutput on reconnectEnd -> undo', inject(function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task1 = elementRegistry.get('Task_1'),
+ task1Bo = task1.businessObject,
+ task2 = elementRegistry.get('Task_2'),
+ task2Bo = task2.businessObject;
+
+ var dataOutputAssociation = modeling.connect(task1, dataObject, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ modeling.reconnectStart(dataOutputAssociation, task2, { x: task2.x, y: task2.y });
+
+ // when
+ commandStack.undo();
+
+ // then
+ var dataOutputAssociationBo = dataOutputAssociation.businessObject;
+
+ expect(getDataOutput(task1Bo, dataOutputAssociationBo.get('sourceRef')[0])).to.exist;
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.eql(getDataOutput(task1Bo, dataOutputAssociationBo.get('sourceRef')[0]));
+
+ expect(getDataOutput(task2Bo, dataOutputAssociationBo.get('sourceRef')[0])).not.to.exist;
+ }));
+
+
+ it('should remove bpmn:DataOutput on remove', inject(function(elementRegistry, modeling) {
+
+ // given
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataOutputAssociation = modeling.connect(task, dataObject, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ modeling.removeElements([ dataOutputAssociation ]);
+
+ // then
+ expect(taskBo.ioSpecification).not.to.exist;
+ }));
+
+
+ it('should add bpmn:DataOutput on remove -> undo', inject(function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject = elementRegistry.get('DataObjectReference_1'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataOutputAssociation = modeling.connect(task, dataObject, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ modeling.removeElements([ dataOutputAssociation ]);
+
+ // when
+ commandStack.undo();
+
+ // then
+ var dataOutputAssociationBo = dataOutputAssociation.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.exist;
+ expect(dataOutputAssociationBo.get('sourceRef')[0]).to.eql(getDataOutput(taskBo, dataOutputAssociationBo.get('sourceRef')[0]));
+ }));
+
+
+ describe('multiple bpmn:DataOutput elements', function() {
+
+ it('should add second bpmn:DataOutput on connect', inject(function(elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataInputAssociation1 = modeling.connect(task, dataObject1, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ var dataInputAssociation2 = modeling.connect(task, dataObject2, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // then
+ var dataInputAssociation1Bo = dataInputAssociation1.businessObject,
+ dataInputAssociation2Bo = dataInputAssociation2.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(taskBo.ioSpecification.dataOutputs).to.have.length(2);
+ expect(taskBo.ioSpecification.outputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets[0].dataOutputRefs).to.have.length(2);
+
+ expect(dataInputAssociation1Bo.get('sourceRef')[0]).to.exist;
+ expect(dataInputAssociation1Bo.get('sourceRef')[0]).to.eql(getDataOutput(taskBo, dataInputAssociation1Bo.get('sourceRef')[0]));
+
+ expect(dataInputAssociation2Bo.get('sourceRef')[0]).to.exist;
+ expect(dataInputAssociation2Bo.get('sourceRef')[0]).to.eql(getDataOutput(taskBo, dataInputAssociation2Bo.get('sourceRef')[0]));
+ }));
+
+
+ it('should remove second bpmn:DataOutput on connect -> undo', inject(function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ var dataInputAssociation1 = modeling.connect(task, dataObject1, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ modeling.connect(task, dataObject2, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ commandStack.undo();
+
+ // then
+ var dataInputAssociation1Bo = dataInputAssociation1.businessObject;
+
+ expect(taskBo.ioSpecification).to.exist;
+ expect(taskBo.ioSpecification.dataOutputs).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets).to.have.length(1);
+ expect(taskBo.ioSpecification.outputSets[0].dataOutputRefs).to.have.length(1);
+
+ expect(dataInputAssociation1Bo.get('sourceRef')[0]).to.exist;
+ expect(dataInputAssociation1Bo.get('sourceRef')[0]).to.eql(getDataOutput(taskBo, dataInputAssociation1Bo.get('sourceRef')[0]));
+ }));
+
+
+ it('should remove all bpmn:DataOutput elements on connect -> connect -> undo -> undo', inject(function(commandStack, elementRegistry, modeling) {
+
+ // given
+ var dataObject1 = elementRegistry.get('DataObjectReference_1'),
+ dataObject2 = elementRegistry.get('DataObjectReference_2'),
+ task = elementRegistry.get('Task_1'),
+ taskBo = task.businessObject;
+
+ modeling.connect(task, dataObject1, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ modeling.connect(task, dataObject2, {
+ type: 'bpmn:DataOutputAssociation'
+ });
+
+ // when
+ commandStack.undo();
+ commandStack.undo();
+
+ // then
+ expect(taskBo.ioSpecification).not.to.exist;
+ }));
+
+ });
+
+});
\ No newline at end of file
diff --git a/test/spec/features/replace/BpmnReplaceSpec.js b/test/spec/features/replace/BpmnReplaceSpec.js
index 6bc9bf911a..9cf62867d4 100644
--- a/test/spec/features/replace/BpmnReplaceSpec.js
+++ b/test/spec/features/replace/BpmnReplaceSpec.js
@@ -344,8 +344,8 @@ describe('features/replace - bpmn replace', function() {
var inputAssociation = inputAssociations[0];
- // expect input association references __target_ref_placeholder property
- expect(inputAssociation.targetRef).to.equal(bo.properties[0]);
+ // expect input association targetRef
+ expect(inputAssociation.targetRef).to.equal(bo.ioSpecification.dataInputs[0]);
// ...and
// expect one outgoing connection