feat(replace): clone properties when morphing to new element
Closes #647
This commit is contained in:
parent
3d0adc6493
commit
a9b68b69e0
|
@ -192,8 +192,7 @@ Modeler.prototype._modelingModules = [
|
|||
require('./features/modeling'),
|
||||
require('./features/palette'),
|
||||
require('./features/replace-preview'),
|
||||
require('./features/snapping'),
|
||||
require('./features/bpmn-clone')
|
||||
require('./features/snapping')
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
__init__: [ 'bpmnClone' ],
|
||||
bpmnClone: [ 'type', require('./BpmnClone') ]
|
||||
};
|
|
@ -2,11 +2,16 @@
|
|||
|
||||
var pick = require('lodash/object/pick'),
|
||||
assign = require('lodash/object/assign'),
|
||||
intersection = require('lodash/array/intersection'),
|
||||
filter = require('lodash/collection/filter'),
|
||||
has = require('lodash/object/has');
|
||||
|
||||
var is = require('../../util/ModelUtil').is,
|
||||
isExpanded = require('../../util/DiUtil').isExpanded,
|
||||
isEventSubProcess = require('../../util/DiUtil').isEventSubProcess;
|
||||
isEventSubProcess = require('../../util/DiUtil').isEventSubProcess,
|
||||
getProperties = require('../../util/model/ModelCloneUtils').getProperties;
|
||||
|
||||
var ModelCloneHelper = require('../../util/model/ModelCloneHelper');
|
||||
|
||||
var CUSTOM_PROPERTIES = [
|
||||
'cancelActivity',
|
||||
|
@ -16,6 +21,21 @@ var CUSTOM_PROPERTIES = [
|
|||
'isInterrupting'
|
||||
];
|
||||
|
||||
var IGNORED_PROPERTIES = [
|
||||
'id',
|
||||
'lanes',
|
||||
'incoming',
|
||||
'outgoing',
|
||||
'eventDefinitions',
|
||||
'processRef',
|
||||
'flowElements',
|
||||
'triggeredByEvent',
|
||||
'dataInputAssociations',
|
||||
'dataOutputAssociations',
|
||||
'incomingConversationLinks',
|
||||
'outgoingConversationLinks'
|
||||
];
|
||||
|
||||
function toggeling(element, target) {
|
||||
|
||||
var oldCollapsed = has(element, 'collapsed') ?
|
||||
|
@ -41,10 +61,13 @@ function toggeling(element, target) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This module takes care of replacing BPMN elements
|
||||
*/
|
||||
function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
||||
function BpmnReplace(bpmnFactory, replace, selection, modeling, moddle) {
|
||||
|
||||
var helper = new ModelCloneHelper(moddle);
|
||||
|
||||
/**
|
||||
* Prepares a new business object for the replacement element
|
||||
|
@ -63,8 +86,6 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
var type = target.type,
|
||||
oldBusinessObject = element.businessObject;
|
||||
|
||||
|
||||
|
||||
if (is(oldBusinessObject, 'bpmn:SubProcess')) {
|
||||
if (type === 'bpmn:SubProcess') {
|
||||
if (toggeling(element, target)) {
|
||||
|
@ -76,7 +97,6 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
var newBusinessObject = bpmnFactory.create(type);
|
||||
|
||||
var newElement = {
|
||||
|
@ -84,6 +104,16 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
businessObject: newBusinessObject
|
||||
};
|
||||
|
||||
var elementProps = getProperties(oldBusinessObject.$descriptor),
|
||||
newElementProps = getProperties(newBusinessObject.$descriptor, true),
|
||||
properties = intersection(elementProps, newElementProps);
|
||||
|
||||
properties = filter(properties, function(property) {
|
||||
return IGNORED_PROPERTIES.indexOf(property.replace(/bpmn:/, '')) === -1;
|
||||
});
|
||||
|
||||
newBusinessObject = helper.clone(oldBusinessObject, newBusinessObject, properties);
|
||||
|
||||
// initialize custom BPMN extensions
|
||||
if (target.eventDefinitionType) {
|
||||
newElement.eventDefinitionType = target.eventDefinitionType;
|
||||
|
@ -162,6 +192,6 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
this.replaceElement = replaceElement;
|
||||
}
|
||||
|
||||
BpmnReplace.$inject = [ 'bpmnFactory', 'replace', 'selection', 'modeling' ];
|
||||
BpmnReplace.$inject = [ 'bpmnFactory', 'replace', 'selection', 'modeling', 'moddle' ];
|
||||
|
||||
module.exports = BpmnReplace;
|
||||
|
|
|
@ -4,4 +4,4 @@ module.exports = {
|
|||
require('diagram-js/lib/features/selection')
|
||||
],
|
||||
bpmnReplace: [ 'type', require('./BpmnReplace') ]
|
||||
};
|
||||
};
|
||||
|
|
|
@ -3,24 +3,33 @@
|
|||
var forEach = require('lodash/collection/forEach'),
|
||||
filter = require('lodash/collection/filter'),
|
||||
isArray = require('lodash/lang/isArray'),
|
||||
contains = require('lodash/collection/contains'),
|
||||
map = require('lodash/collection/map');
|
||||
contains = require('lodash/collection/contains');
|
||||
|
||||
|
||||
function isAllowedIn(extProp, type) {
|
||||
var allowedIn = extProp.meta.allowedIn;
|
||||
|
||||
// '*' is a wildcard, which means any element is allowed to use this property
|
||||
if (allowedIn.length === 1 && allowedIn[0] === '*') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return allowedIn.indexOf(type) !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* A bpmn properties cloning interface
|
||||
*
|
||||
* @param {Moddle} moddle
|
||||
*/
|
||||
function BpmnClone(moddle) {
|
||||
function ModelCloneHelper(moddle) {
|
||||
this._moddle = moddle;
|
||||
}
|
||||
|
||||
module.exports = BpmnClone;
|
||||
|
||||
BpmnClone.$inject = [ 'moddle' ];
|
||||
module.exports = ModelCloneHelper;
|
||||
|
||||
|
||||
BpmnClone.prototype.clone = function(oldElement, newElement, properties) {
|
||||
ModelCloneHelper.prototype.clone = function(oldElement, newElement, properties) {
|
||||
var moddle = this._moddle;
|
||||
|
||||
forEach(properties, function(propName) {
|
||||
|
@ -45,10 +54,12 @@ BpmnClone.prototype.clone = function(oldElement, newElement, properties) {
|
|||
|
||||
var extProp = moddle.registry.typeMap[extElement.$type];
|
||||
|
||||
if (extProp.meta.allowedIn && extProp.meta.allowedIn.indexOf(newElement.$type) !== -1) {
|
||||
if (extProp.meta.allowedIn && isAllowedIn(extProp, newElement.$type)) {
|
||||
|
||||
var newProp = this._deepClone(extElement);
|
||||
|
||||
newProp.$parent = newElement.extensionElements;
|
||||
|
||||
newElement.extensionElements.values.push(newProp);
|
||||
}
|
||||
}, this);
|
||||
|
@ -58,6 +69,8 @@ BpmnClone.prototype.clone = function(oldElement, newElement, properties) {
|
|||
forEach(oldElementProp, function(extElement) {
|
||||
var newProp = this._deepClone(extElement);
|
||||
|
||||
newProp.$parent = newElement;
|
||||
|
||||
newElement.documentation.push(newProp);
|
||||
}, this);
|
||||
}
|
||||
|
@ -66,19 +79,9 @@ BpmnClone.prototype.clone = function(oldElement, newElement, properties) {
|
|||
return newElement;
|
||||
};
|
||||
|
||||
BpmnClone.prototype._deepClone = function _deepClone(extElement) {
|
||||
ModelCloneHelper.prototype._deepClone = function _deepClone(extElement) {
|
||||
var newProp = extElement.$model.create(extElement.$type),
|
||||
properties;
|
||||
|
||||
// figure out which properties we want to assign to the newElement
|
||||
// we're interested in enumerable ones (todo: double check this)
|
||||
if (isArray(extElement)) {
|
||||
properties = map(extElement, function(item) {
|
||||
return item.$type;
|
||||
});
|
||||
} else {
|
||||
properties = filter(Object.keys(extElement), function(prop) { return prop !== '$type'; });
|
||||
}
|
||||
properties = filter(Object.keys(extElement), function(prop) { return prop !== '$type'; });
|
||||
|
||||
forEach(properties, function(propName) {
|
||||
// check if the extElement has this property defined
|
||||
|
@ -88,11 +91,17 @@ BpmnClone.prototype._deepClone = function _deepClone(extElement) {
|
|||
newProp[propName] = [];
|
||||
|
||||
forEach(extElement[propName], function(property) {
|
||||
newProp[propName].push(this._deepClone(property));
|
||||
var newDeepProp = this._deepClone(property);
|
||||
|
||||
newDeepProp.$parent = newProp;
|
||||
|
||||
newProp[propName].push(newDeepProp);
|
||||
}, this);
|
||||
|
||||
} else if (extElement[propName].$type) {
|
||||
newProp[propName] = this._deepClone(extElement[propName]);
|
||||
|
||||
newProp[propName].$parent = newProp;
|
||||
}
|
||||
} else {
|
||||
// just assign directly if it's a value
|
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
var forEach = require('lodash/collection/forEach');
|
||||
|
||||
function getProperties(descriptor, keepDefault) {
|
||||
var properties = [];
|
||||
|
||||
forEach(descriptor.properties, function(property) {
|
||||
|
||||
if (keepDefault && property.default) {
|
||||
return;
|
||||
}
|
||||
|
||||
properties.push(property.ns.name);
|
||||
});
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
module.exports.getProperties = getProperties;
|
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.7.0-dev">
|
||||
<bpmn:collaboration id="Collaboration_0j2pyna">
|
||||
<bpmn:participant id="Participant_0x9lnke" processRef="Process_1" />
|
||||
</bpmn:collaboration>
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:dataStoreReference id="DataStoreReference_1elrt45" />
|
||||
<bpmn:dataStoreReference id="DataStoreReference_1j8ymac" />
|
||||
<bpmn:dataObjectReference id="DataObjectReference_1js94kb" dataObjectRef="DataObject_1l0h55k" />
|
||||
<bpmn:dataObject id="DataObject_1l0h55k" />
|
||||
<bpmn:dataObjectReference id="DataObjectReference_0hkbt95" dataObjectRef="DataObject_1iu55n1" />
|
||||
<bpmn:dataObject id="DataObject_1iu55n1" />
|
||||
<bpmn:subProcess id="SubProcess_04tmqcs">
|
||||
<bpmn:userTask id="Task_1" camunda:asyncBefore="true" camunda:jobPriority="100">
|
||||
<bpmn:documentation>hello world</bpmn:documentation>
|
||||
<bpmn:extensionElements>
|
||||
<camunda:inputOutput>
|
||||
<camunda:inputParameter name="Input_1">foo</camunda:inputParameter>
|
||||
<camunda:outputParameter name="Output_1">bar</camunda:outputParameter>
|
||||
</camunda:inputOutput>
|
||||
<camunda:properties>
|
||||
<camunda:property name="bar" value="foo" />
|
||||
</camunda:properties>
|
||||
<camunda:executionListener class="reallyClassy" event="start" />
|
||||
<camunda:failedJobRetryTimeCycle>10</camunda:failedJobRetryTimeCycle>
|
||||
<camunda:taskListener class="foobar" event="create" />
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>SequenceFlow_1e74z8m</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_1tdxph9</bpmn:outgoing>
|
||||
<bpmn:property id="Property_0j0o7pl" name="__targetRef_placeholder" />
|
||||
<bpmn:dataInputAssociation id="DataInputAssociation_0xdwl7n">
|
||||
<bpmn:sourceRef>DataStoreReference_1elrt45</bpmn:sourceRef>
|
||||
<bpmn:targetRef>Property_0j0o7pl</bpmn:targetRef>
|
||||
</bpmn:dataInputAssociation>
|
||||
<bpmn:dataInputAssociation id="DataInputAssociation_188je0k">
|
||||
<bpmn:sourceRef>DataObjectReference_0hkbt95</bpmn:sourceRef>
|
||||
<bpmn:targetRef>Property_0j0o7pl</bpmn:targetRef>
|
||||
</bpmn:dataInputAssociation>
|
||||
<bpmn:dataOutputAssociation id="DataOutputAssociation_1wf2bxo">
|
||||
<bpmn:targetRef>DataStoreReference_1j8ymac</bpmn:targetRef>
|
||||
</bpmn:dataOutputAssociation>
|
||||
<bpmn:dataOutputAssociation id="DataOutputAssociation_0hr21ne">
|
||||
<bpmn:targetRef>DataObjectReference_1js94kb</bpmn:targetRef>
|
||||
</bpmn:dataOutputAssociation>
|
||||
</bpmn:userTask>
|
||||
<bpmn:startEvent id="StartEvent_1a4dsh8">
|
||||
<bpmn:outgoing>SequenceFlow_1e74z8m</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1e74z8m" sourceRef="StartEvent_1a4dsh8" targetRef="Task_1" />
|
||||
<bpmn:task id="Task_042z61e">
|
||||
<bpmn:incoming>SequenceFlow_1tdxph9</bpmn:incoming>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1tdxph9" sourceRef="Task_1" targetRef="Task_042z61e" />
|
||||
</bpmn:subProcess>
|
||||
<bpmn:textAnnotation id="TextAnnotation_1cghzwc" />
|
||||
<bpmn:association id="Association_0edc446" sourceRef="Task_1" targetRef="TextAnnotation_1cghzwc" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_0j2pyna">
|
||||
<bpmndi:BPMNShape id="UserTask_033cl9l_di" bpmnElement="Task_1">
|
||||
<dc:Bounds x="261" y="159.5" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="StartEvent_1a4dsh8_di" bpmnElement="StartEvent_1a4dsh8">
|
||||
<dc:Bounds x="168" y="181.5" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="186" y="217.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1e74z8m_di" bpmnElement="SequenceFlow_1e74z8m">
|
||||
<di:waypoint xsi:type="dc:Point" x="204" y="199.5" />
|
||||
<di:waypoint xsi:type="dc:Point" x="261" y="199.5" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="233" y="174.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Task_042z61e_di" bpmnElement="Task_042z61e">
|
||||
<dc:Bounds x="441" y="159.5" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1tdxph9_di" bpmnElement="SequenceFlow_1tdxph9">
|
||||
<di:waypoint xsi:type="dc:Point" x="361" y="199.5" />
|
||||
<di:waypoint xsi:type="dc:Point" x="441" y="199.5" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="401" y="184.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Participant_0x9lnke_di" bpmnElement="Participant_0x9lnke">
|
||||
<dc:Bounds x="0" y="0" width="632" height="417" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="TextAnnotation_1cghzwc_di" bpmnElement="TextAnnotation_1cghzwc">
|
||||
<dc:Bounds x="50" y="30.5" width="100" height="30" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataStoreReference_1elrt45_di" bpmnElement="DataStoreReference_1elrt45">
|
||||
<dc:Bounds x="211" y="347.5" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="236" y="397.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataStoreReference_1j8ymac_di" bpmnElement="DataStoreReference_1j8ymac">
|
||||
<dc:Bounds x="345" y="347.5" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="370" y="397.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataObjectReference_1js94kb_di" bpmnElement="DataObjectReference_1js94kb">
|
||||
<dc:Bounds x="352" y="20.5" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="370" y="70.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataObjectReference_0hkbt95_di" bpmnElement="DataObjectReference_0hkbt95">
|
||||
<dc:Bounds x="218" y="20.5" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="236" y="70.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="SubProcess_04tmqcs_di" bpmnElement="SubProcess_04tmqcs" isExpanded="true">
|
||||
<dc:Bounds x="153" y="104.5" width="459" height="200" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Association_0edc446_di" bpmnElement="Association_0edc446">
|
||||
<di:waypoint xsi:type="dc:Point" x="265" y="165.5" />
|
||||
<di:waypoint xsi:type="dc:Point" x="121" y="60.5" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="DataInputAssociation_0xdwl7n_di" bpmnElement="DataInputAssociation_0xdwl7n">
|
||||
<di:waypoint xsi:type="dc:Point" x="244" y="347.5" />
|
||||
<di:waypoint xsi:type="dc:Point" x="276" y="239.5" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="DataOutputAssociation_1wf2bxo_di" bpmnElement="DataOutputAssociation_1wf2bxo">
|
||||
<di:waypoint xsi:type="dc:Point" x="323" y="239.5" />
|
||||
<di:waypoint xsi:type="dc:Point" x="354" y="347.5" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="DataOutputAssociation_0hr21ne_di" bpmnElement="DataOutputAssociation_0hr21ne">
|
||||
<di:waypoint xsi:type="dc:Point" x="329" y="159.5" />
|
||||
<di:waypoint xsi:type="dc:Point" x="368" y="70.5" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="DataInputAssociation_188je0k_di" bpmnElement="DataInputAssociation_188je0k">
|
||||
<di:waypoint xsi:type="dc:Point" x="245" y="70.5" />
|
||||
<di:waypoint xsi:type="dc:Point" x="275" y="159.5" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -460,6 +460,9 @@
|
|||
"superClass": [
|
||||
"Element"
|
||||
],
|
||||
"meta": {
|
||||
"allowedIn": [ "*" ]
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"name": "values",
|
||||
|
|
|
@ -1169,4 +1169,69 @@ describe('features/replace - bpmn replace', function() {
|
|||
|
||||
});
|
||||
|
||||
|
||||
describe('properties', function() {
|
||||
var clonePropertiesXML = require('../../../fixtures/bpmn/features/replace/clone-properties.bpmn');
|
||||
|
||||
var camundaPackage = require('../../../fixtures/json/model/camunda');
|
||||
|
||||
beforeEach(bootstrapModeler(clonePropertiesXML, {
|
||||
modules: testModules,
|
||||
moddleExtensions: {
|
||||
camunda: camundaPackage
|
||||
}
|
||||
}));
|
||||
|
||||
it('should copy properties', inject(function(elementRegistry, bpmnReplace) {
|
||||
// given
|
||||
var task = elementRegistry.get('Task_1');
|
||||
var newElementData = {
|
||||
type: 'bpmn:ServiceTask'
|
||||
};
|
||||
|
||||
// when
|
||||
var newElement = bpmnReplace.replaceElement(task, newElementData);
|
||||
|
||||
// then
|
||||
var businessObject = newElement.businessObject;
|
||||
|
||||
expect(businessObject.asyncBefore).to.be.true;
|
||||
expect(businessObject.jobPriority).to.equal('100');
|
||||
expect(businessObject.documentation[0].text).to.equal('hello world');
|
||||
|
||||
var extensionElements = businessObject.extensionElements.values;
|
||||
|
||||
expect(extensionElements).to.have.length(4);
|
||||
|
||||
expect(is(extensionElements[0], 'camunda:InputOutput')).to.be.true;
|
||||
|
||||
expect(is(extensionElements[0].inputParameters[0], 'camunda:InputParameter')).to.be.true;
|
||||
|
||||
expect(extensionElements[0].inputParameters[0].name).to.equal('Input_1');
|
||||
expect(extensionElements[0].inputParameters[0].value).to.equal('foo');
|
||||
|
||||
expect(is(extensionElements[0].outputParameters[0], 'camunda:OutputParameter')).to.be.true;
|
||||
|
||||
expect(extensionElements[0].outputParameters[0].name).to.equal('Output_1');
|
||||
expect(extensionElements[0].outputParameters[0].value).to.equal('bar');
|
||||
|
||||
expect(is(extensionElements[1], 'camunda:Properties')).to.be.true;
|
||||
|
||||
expect(is(extensionElements[1].values[0], 'camunda:Property')).to.be.true;
|
||||
|
||||
expect(extensionElements[1].values[0].name).to.equal('bar');
|
||||
expect(extensionElements[1].values[0].value).to.equal('foo');
|
||||
|
||||
expect(is(extensionElements[2], 'camunda:ExecutionListener')).to.be.true;
|
||||
|
||||
expect(extensionElements[2].class).to.equal('reallyClassy');
|
||||
expect(extensionElements[2].event).to.equal('start');
|
||||
|
||||
expect(is(extensionElements[3], 'camunda:FailedJobRetryTimeCycle')).to.be.true;
|
||||
|
||||
expect(extensionElements[3].body).to.equal('10');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
require('../../../TestHelper');
|
||||
require('../../TestHelper');
|
||||
|
||||
/* global bootstrapModeler, inject */
|
||||
|
||||
var bpmnCloneModule = require('../../../../lib/features/bpmn-clone'),
|
||||
coreModule = require('../../../../lib/core');
|
||||
var coreModule = require('../../../lib/core');
|
||||
|
||||
var camundaPackage = require('../../../fixtures/json/model/camunda');
|
||||
var ModelCloneHelper = require('../../../lib/util/model/ModelCloneHelper');
|
||||
|
||||
var camundaPackage = require('../../fixtures/json/model/camunda');
|
||||
|
||||
function getProp(element, property) {
|
||||
return element && element.$model.properties.get(element, property);
|
||||
}
|
||||
|
||||
describe('features/bpmn-clone', function() {
|
||||
describe('util/ModelCloneHelper', function() {
|
||||
|
||||
var testModules = [ bpmnCloneModule, coreModule ];
|
||||
var testModules = [ coreModule ];
|
||||
|
||||
var basicXML = require('../../../fixtures/bpmn/basic.bpmn');
|
||||
var basicXML = require('../../fixtures/bpmn/basic.bpmn');
|
||||
|
||||
beforeEach(bootstrapModeler(basicXML, {
|
||||
modules: testModules,
|
||||
|
@ -26,33 +27,35 @@ describe('features/bpmn-clone', function() {
|
|||
}
|
||||
}));
|
||||
|
||||
var helper;
|
||||
|
||||
beforeEach(inject(function(moddle) {
|
||||
helper = new ModelCloneHelper(moddle);
|
||||
}));
|
||||
|
||||
describe('simple', function() {
|
||||
|
||||
it('should pass property', inject(function(moddle, bpmnClone) {
|
||||
it('should pass property', inject(function(moddle) {
|
||||
|
||||
// given
|
||||
var userTask = moddle.create('bpmn:UserTask', {
|
||||
name: 'Field_1',
|
||||
stringValue: 'myFieldValue',
|
||||
asyncBefore: true
|
||||
});
|
||||
|
||||
var serviceTask = bpmnClone.clone(userTask, moddle.create('bpmn:ServiceTask'), [ 'camunda:asyncBefore' ]);
|
||||
var serviceTask = helper.clone(userTask, moddle.create('bpmn:ServiceTask'), [ 'camunda:asyncBefore' ]);
|
||||
|
||||
expect(getProp(serviceTask, 'camunda:asyncBefore')).to.be.true;
|
||||
}));
|
||||
|
||||
|
||||
it('should not pass property', inject(function(bpmnClone, moddle) {
|
||||
it('should not pass property', inject(function(moddle) {
|
||||
|
||||
// given
|
||||
var userTask = moddle.create('bpmn:UserTask', {
|
||||
name: 'Field_1',
|
||||
stringValue: 'myFieldValue',
|
||||
assignee: 'foobar'
|
||||
});
|
||||
|
||||
var serviceTask = bpmnClone.clone(userTask, moddle.create('bpmn:ServiceTask'), []);
|
||||
var serviceTask = helper.clone(userTask, moddle.create('bpmn:ServiceTask'), []);
|
||||
|
||||
expect(getProp(serviceTask, 'camunda:assignee')).to.not.exist;
|
||||
}));
|
||||
|
@ -61,26 +64,25 @@ describe('features/bpmn-clone', function() {
|
|||
|
||||
describe('nested', function() {
|
||||
|
||||
it('should pass nested property - documentation', inject(function(moddle, bpmnClone) {
|
||||
it('should pass nested property - documentation', inject(function(moddle) {
|
||||
|
||||
// given
|
||||
var userTask = moddle.create('bpmn:UserTask', {
|
||||
name: 'Field_1',
|
||||
stringValue: 'myFieldValue'
|
||||
});
|
||||
var userTask = moddle.create('bpmn:UserTask');
|
||||
|
||||
var docs = userTask.get('documentation');
|
||||
|
||||
docs.push(moddle.create('bpmn:Documentation', { textFormat: 'xyz', text: 'FOO\nBAR' }));
|
||||
docs.push(moddle.create('bpmn:Documentation', { text: '<some /><html></html>' }));
|
||||
|
||||
var serviceTask = bpmnClone.clone(userTask, moddle.create('bpmn:ServiceTask'), [ 'bpmn:documentation' ]);
|
||||
var serviceTask = helper.clone(userTask, moddle.create('bpmn:ServiceTask'), [ 'bpmn:documentation' ]);
|
||||
|
||||
var serviceTaskDocs = getProp(serviceTask, 'bpmn:documentation'),
|
||||
userTaskDocs = getProp(userTask, 'bpmn:documentation');
|
||||
|
||||
expect(userTaskDocs[0]).to.not.equal(serviceTaskDocs[0]);
|
||||
|
||||
expect(serviceTaskDocs[0].$parent).to.equal(serviceTask);
|
||||
|
||||
expect(serviceTaskDocs[0].text).to.equal('FOO\nBAR');
|
||||
expect(serviceTaskDocs[0].textFormat).to.equal('xyz');
|
||||
|
||||
|
@ -88,7 +90,7 @@ describe('features/bpmn-clone', function() {
|
|||
}));
|
||||
|
||||
|
||||
it('should pass deeply nested property - executionListener', inject(function(moddle, bpmnClone) {
|
||||
it('should pass deeply nested property - executionListener', inject(function(moddle) {
|
||||
|
||||
// given
|
||||
var script = moddle.create('camunda:Script', {
|
||||
|
@ -104,12 +106,10 @@ describe('features/bpmn-clone', function() {
|
|||
var extensionElements = moddle.create('bpmn:ExtensionElements', { values: [ execListener ] });
|
||||
|
||||
var userTask = moddle.create('bpmn:UserTask', {
|
||||
name: 'Field_1',
|
||||
stringValue: 'myFieldValue',
|
||||
extensionElements: extensionElements
|
||||
});
|
||||
|
||||
var serviceTask = bpmnClone.clone(userTask, moddle.create('bpmn:ServiceTask'), [
|
||||
var serviceTask = helper.clone(userTask, moddle.create('bpmn:ServiceTask'), [
|
||||
'bpmn:extensionElements',
|
||||
'camunda:executionListener'
|
||||
]);
|
||||
|
@ -118,15 +118,19 @@ describe('features/bpmn-clone', function() {
|
|||
|
||||
// then
|
||||
expect(executionListener.$type).to.equal('camunda:ExecutionListener');
|
||||
expect(executionListener.$parent).to.equal(serviceTask.extensionElements);
|
||||
|
||||
expect(executionListener.event).to.equal('start');
|
||||
|
||||
expect(executionListener.script.$type).to.equal('camunda:Script');
|
||||
expect(executionListener.script.$parent).to.equal(executionListener);
|
||||
|
||||
expect(executionListener.script.scriptFormat).to.equal('groovy');
|
||||
expect(executionListener.script.value).to.equal('foo = bar;');
|
||||
}));
|
||||
|
||||
|
||||
it('should pass deeply nested property - inputOutput', inject(function(moddle, bpmnClone) {
|
||||
it('should pass deeply nested property - inputOutput', inject(function(moddle) {
|
||||
|
||||
// given
|
||||
var outputParameter = moddle.create('camunda:OutputParameter', {
|
||||
|
@ -147,12 +151,10 @@ describe('features/bpmn-clone', function() {
|
|||
var extensionElements = moddle.create('bpmn:ExtensionElements', { values: [ inputOutput ] });
|
||||
|
||||
var userTask = moddle.create('bpmn:UserTask', {
|
||||
name: 'Field_1',
|
||||
stringValue: 'myFieldValue',
|
||||
extensionElements: extensionElements
|
||||
});
|
||||
|
||||
var serviceTask = bpmnClone.clone(userTask, moddle.create('bpmn:ServiceTask'), [
|
||||
var serviceTask = helper.clone(userTask, moddle.create('bpmn:ServiceTask'), [
|
||||
'bpmn:extensionElements',
|
||||
'camunda:inputOutput'
|
||||
]);
|
||||
|
@ -166,9 +168,15 @@ describe('features/bpmn-clone', function() {
|
|||
var oldOutParam = userTask.extensionElements.values[0].outputParameters[0];
|
||||
|
||||
expect(newOutParam).to.not.equal(oldOutParam);
|
||||
|
||||
expect(newOutParam.$parent).to.equal(executionListener);
|
||||
expect(newOutParam.definition).to.not.equal(oldOutParam.definition);
|
||||
expect(newOutParam.definition.$parent).to.equal(newOutParam);
|
||||
|
||||
expect(newOutParam.definition.items[0]).to.not.equal(oldOutParam.definition.items[0]);
|
||||
|
||||
expect(newOutParam.definition.items[0].$parent).to.not.equal(newOutParam.definition.$parent);
|
||||
|
||||
expect(newOutParam.$type).to.equal('camunda:OutputParameter');
|
||||
expect(newOutParam.definition.$type).to.equal('camunda:List');
|
||||
expect(newOutParam.definition.items[0].value).to.equal('${1+1}');
|
Loading…
Reference in New Issue