From fefc748a9a2d407a2137efe3ecc67fb588c9d955 Mon Sep 17 00:00:00 2001 From: Nico Rehwaldt Date: Sat, 10 Oct 2015 01:41:32 +0200 Subject: [PATCH] feat(snapping): add lane snapping --- lib/features/snapping/BpmnSnapping.js | 200 ++++++++---- lib/features/snapping/BpmnSnappingUtil.js | 149 ++++++++- .../features/snapping/BpmnSnappingSpec.js | 43 ++- .../BpmnSnappingUtil.lanes-flowNodes.bpmn | 83 +++++ .../snapping/BpmnSnappingUtil.lanes.bpmn | 36 +++ .../features/snapping/BpmnSnappingUtilSpec.js | 286 ++++++++++++++++++ 6 files changed, 719 insertions(+), 78 deletions(-) create mode 100644 test/spec/features/snapping/BpmnSnappingUtil.lanes-flowNodes.bpmn create mode 100644 test/spec/features/snapping/BpmnSnappingUtil.lanes.bpmn create mode 100644 test/spec/features/snapping/BpmnSnappingUtilSpec.js diff --git a/lib/features/snapping/BpmnSnapping.js b/lib/features/snapping/BpmnSnapping.js index 63c8ca1c..654f5e7b 100644 --- a/lib/features/snapping/BpmnSnapping.js +++ b/lib/features/snapping/BpmnSnapping.js @@ -5,14 +5,15 @@ var inherits = require('inherits'); var forEach = require('lodash/collection/forEach'); var getBoundingBox = require('diagram-js/lib/util/Elements').getBBox; -var is = require('../modeling/ModelingUtil').is, + +var is = require('../../util/ModelUtil').is, + isAny = require('../modeling/util/ModelingUtil').isAny, isExpanded = require('../../util/DiUtil').isExpanded; var Snapping = require('diagram-js/lib/features/snapping/Snapping'), SnapUtil = require('diagram-js/lib/features/snapping/SnapUtil'); -var is = require('../../util/ModelUtil').is; - +var asTRBL = require('diagram-js/lib/layout/LayoutUtil').asTRBL; var round = Math.round; @@ -20,8 +21,12 @@ var mid = SnapUtil.mid, topLeft = SnapUtil.topLeft, bottomRight = SnapUtil.bottomRight, isSnapped = SnapUtil.isSnapped, - setSnapped = SnapUtil.setSnapped, - getBoundaryAttachment = require('./BpmnSnappingUtil').getBoundaryAttachment; + setSnapped = SnapUtil.setSnapped; + +var getBoundaryAttachment = require('./BpmnSnappingUtil').getBoundaryAttachment, + getParticipantSizeConstraints = require('./BpmnSnappingUtil').getParticipantSizeConstraints, + getLanesRoot = require('../modeling/util/LaneUtil').getLanesRoot; + /** * BPMN specific snapping functionality @@ -32,7 +37,7 @@ var mid = SnapUtil.mid, * @param {EventBus} eventBus * @param {Canvas} canvas */ -function BpmnSnapping(eventBus, canvas, bpmnRules) { +function BpmnSnapping(eventBus, canvas, bpmnRules, elementRegistry) { // instantiate super Snapping.call(this, eventBus, canvas); @@ -84,7 +89,12 @@ function BpmnSnapping(eventBus, canvas, bpmnRules) { /** * Snap boundary events to elements border */ - eventBus.on([ 'create.move', 'create.end' ], 1500, function(event) { + eventBus.on([ + 'create.move', + 'create.end', + 'shape.move.move', + 'shape.move.end' + ], 1500, function(event) { var context = event.context, target = context.target, @@ -95,32 +105,132 @@ function BpmnSnapping(eventBus, canvas, bpmnRules) { } }); - eventBus.on([ 'shape.move.move', 'shape.move.end' ], 1500, function(event) { - + /** + * Adjust parent for flowElements to the target participant + * when droping onto lanes. + */ + eventBus.on([ + 'shape.move.hover', + 'shape.move.move', + 'shape.move.end', + 'create.hover', + 'create.move', + 'create.end' + ], 1500, function(event) { var context = event.context, - target = context.target, - shape = context.shape; + shape = context.shape, + hover = event.hover; - if (target && !isSnapped(event) && canAttach(shape, target, event)) { - snapBoundaryEvent(event, shape, target); + if (is(hover, 'bpmn:Lane') && !isAny(shape, [ 'bpmn:Lane', 'bpmn:Participant' ])) { + event.hover = getLanesRoot(hover); + event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); + var abs = Math.abs; + + var filter = require('lodash/collection/filter'), + assign = require('lodash/object/assign'); + + + eventBus.on([ + 'create.move', + 'shape.move.move' + ], function(event) { + + var context = event.context, + shape = context.shape, + target = context.target; + + var threshold = 30; + + if (is(shape, 'bpmn:Lane')) { + if (isAny(target, [ 'bpmn:Lane', 'bpmn:Participant' ])) { + + var childLanes = filter(target.children, function(c) { + return is(c, 'bpmn:Lane'); + }); + + var y = event.y, + targetTrbl; + + var insert = childLanes.reduce(function(insert, l) { + + var laneTrbl = asTRBL(l); + + if (abs(laneTrbl.top - y) < threshold) { + insert = assign(insert || {}, { before: { element: l, y: laneTrbl.top } }); + } else + if (abs(laneTrbl.bottom - y) < threshold) { + insert = assign(insert || {}, { after: { element: l, y: laneTrbl.bottom } }); + } else + if (laneTrbl.top < y && laneTrbl.bottom > y) { + if (abs(laneTrbl.top - y) > abs(laneTrbl.bottom - y)) { + insert = assign(insert || {}, { after: { element: l, y: laneTrbl.bottom } }); + } else { + insert = assign(insert || {}, { before: { element: l, y: laneTrbl.top } }); + } + + } + + return insert; + }, false); + + + if (!insert) { + targetTrbl = asTRBL(target); + + if (abs(targetTrbl.top - y) < threshold) { + insert = { before: { element: target, y: targetTrbl.top } }; + } else + if (abs(targetTrbl.bottom - y) < threshold) { + insert = { after: { element: target, y: targetTrbl.bottom } }; + } else { + insert = { into: { element: target, y: (targetTrbl.top + targetTrbl.bottom) / 2 } }; + } + + } + + if (insert.before && insert.after) { + console.log('insert between', insert.before.element.id, 'and', insert.after.element.id); + setSnapped(event, 'x', insert.before.element.x + insert.before.element.width / 2); + setSnapped(event, 'y', insert.before.y); + } else + if (insert.after) { + console.log('insert after', insert.after.element.id); + setSnapped(event, 'x', insert.after.element.x + insert.after.element.width / 2); + setSnapped(event, 'y', insert.after.y); + } else + if (insert.before) { + console.log('insert before', insert.before.element.id); + setSnapped(event, 'x', insert.before.element.x + insert.before.element.width / 2); + setSnapped(event, 'y', insert.before.y); + } else + if (insert.into) { + console.log('insert into', insert.into.element.id); + setSnapped(event, 'x', insert.into.element.x + insert.into.element.width / 2); + setSnapped(event, 'y', insert.into.y); + } + } + } + + }); + eventBus.on('resize.start', 1500, function(event) { var context = event.context, shape = context.shape; if (is(shape, 'bpmn:SubProcess') && isExpanded(shape)) { - context.minDimensions = { width: 140, height: 120 }; + context.minDimensions = { width: 140, height: 120 }; } if (is(shape, 'bpmn:Participant')) { context.minDimensions = { width: 300, height: 150 }; } - if (is(shape, 'bpmn:Participant') || is(shape, 'bpmn:Lane')) { - context.minBounds = computeParticipantMinBounds(shape); + if (is(shape, 'bpmn:Lane') || is(shape, 'bpmn:Participant')) { + context.resizeConstraints = getParticipantSizeConstraints(shape, context.direction); } if (is(shape, 'bpmn:TextAnnotation')) { @@ -132,7 +242,7 @@ function BpmnSnapping(eventBus, canvas, bpmnRules) { inherits(BpmnSnapping, Snapping); -BpmnSnapping.$inject = [ 'eventBus', 'canvas', 'bpmnRules' ]; +BpmnSnapping.$inject = [ 'eventBus', 'canvas', 'bpmnRules', 'elementRegistry' ]; module.exports = BpmnSnapping; @@ -227,6 +337,12 @@ BpmnSnapping.prototype.addTargetSnaps = function(snapPoints, shape, target) { var siblings = this.getSiblings(shape, target) || []; forEach(siblings, function(s) { + + // do not snap to lanes + if (is(s, 'bpmn:Lane')) { + return; + } + snapPoints.add('mid', mid(s)); if (is(s, 'bpmn:Participant')) { @@ -321,11 +437,8 @@ function snapParticipant(snapBox, shape, event, offset) { /////// boundary event snapping ///////////////////////// -var LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); - - function snapBoundaryEvent(event, shape, target) { - var targetTRBL = LayoutUtil.asTRBL(target); + var targetTRBL = asTRBL(target); var direction = getBoundaryAttachment(event, target); @@ -342,47 +455,4 @@ function snapBoundaryEvent(event, shape, target) { if (/right/.test(direction)) { setSnapped(event, 'x', targetTRBL.right); } -} - - -//////// participant / lane min bounds - -var getBBox = require('diagram-js/lib/util/Elements').getBBox, - addPadding = require('diagram-js/lib/features/resize/ResizeUtil').addPadding; - -function computeParticipantMinBounds(element) { - - var lanePadding = { - left: 30, - top: 0, - right: 0, - bottom: 0 - }; - - var flowElementPadding = { - left: 50, - right: 35 - }; - - function getChildBox(child) { - if (is(child, 'bpmn:Lane')) { - return addPadding(child, lanePadding); - } - - if (child.labelTarget || child.waypoints) { - return null; - } - - return addPadding(child, flowElementPadding); - } - - function nonNull(e) { - return !!e; - } - - var childrenBoxes = element.children.map(getChildBox).filter(nonNull); - - if (childrenBoxes.length) { - return getBBox(childrenBoxes); - } -} +} \ No newline at end of file diff --git a/lib/features/snapping/BpmnSnappingUtil.js b/lib/features/snapping/BpmnSnappingUtil.js index b5b89b49..9c13640f 100644 --- a/lib/features/snapping/BpmnSnappingUtil.js +++ b/lib/features/snapping/BpmnSnappingUtil.js @@ -3,7 +3,7 @@ var getOrientation = require('diagram-js/lib/layout/LayoutUtil').getOrientation; -module.exports.getBoundaryAttachment = function(position, targetBounds) { +function getBoundaryAttachment(position, targetBounds) { var orientation = getOrientation(position, targetBounds, -15); @@ -12,4 +12,149 @@ module.exports.getBoundaryAttachment = function(position, targetBounds) { } else { return null; } -}; \ No newline at end of file +} + +module.exports.getBoundaryAttachment = getBoundaryAttachment; + + + +// participant snapping box implementation ///////////////// + +var is = require('../../util/ModelUtil').is; + +var asTRBL = require('diagram-js/lib/layout/LayoutUtil').asTRBL; + +var collectLanes = require('../modeling/util/LaneUtil').collectLanes, + getLanesRoot = require('../modeling/util/LaneUtil').getLanesRoot; + +var abs = Math.abs, + min = Math.min, + max = Math.max; + + +function addToTrbl(trbl, attr, value, choice) { + + var current = trbl[attr]; + + // make sure to set the value if it does not exist + // or apply the correct value by comparing against + // choice(value, currentValue) + trbl[attr] = current === undefined ? value : choice(value, current); +} + +function addMin(trbl, attr, value) { + return addToTrbl(trbl, attr, value, min); +} + +function addMax(trbl, attr, value) { + return addToTrbl(trbl, attr, value, max); +} + + +var LANE_MIN_HEIGHT = 60, + LANE_MIN_WIDTH = 300, + LANE_RIGHT_PADDING = 20, + LANE_LEFT_PADDING = 50, + LANE_TOP_PADDING = 20, + LANE_BOTTOM_PADDING = 20; + + +function getParticipantSizeConstraints(laneShape, resizeDirection) { + + var lanesRoot = getLanesRoot(laneShape); + + var isFirst = true, + isLast = true; + + ///// max top/bottom size for lanes + + var allLanes = collectLanes(lanesRoot, [ lanesRoot ]); + + var laneTrbl = asTRBL(laneShape); + + var maxTrbl = {}, + minTrbl = {}; + + if (/e/.test(resizeDirection)) { + minTrbl.right = laneTrbl.left + LANE_MIN_WIDTH; + } else + if (/w/.test(resizeDirection)) { + minTrbl.left = laneTrbl.right - LANE_MIN_WIDTH; + } + + allLanes.forEach(function(other) { + + var otherTrbl = asTRBL(other); + + if (/n/.test(resizeDirection)) { + + if (otherTrbl.top < (laneTrbl.top - 10)) { + isFirst = false; + } + + // max top size (based on next element) + if (abs(laneTrbl.top - otherTrbl.bottom) < 10) { + addMax(maxTrbl, 'top', otherTrbl.top + LANE_MIN_HEIGHT); + } + + // min top size (based on self or nested element) + if (abs(laneTrbl.top - otherTrbl.top) < 5) { + addMin(minTrbl, 'top', otherTrbl.bottom - LANE_MIN_HEIGHT); + } + } + + if (/s/.test(resizeDirection)) { + + if (otherTrbl.bottom > (laneTrbl.bottom + 10)) { + isLast = false; + } + + // max bottom size (based on previous element) + if (abs(laneTrbl.bottom - otherTrbl.top) < 10) { + addMin(maxTrbl, 'bottom', otherTrbl.bottom - LANE_MIN_HEIGHT); + } + + // min bottom size (based on self or nested element) + if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) { + addMax(minTrbl, 'bottom', otherTrbl.top + LANE_MIN_HEIGHT); + } + } + }); + + + ///// max top/bottom/left/right size based on flow nodes + + var flowElements = lanesRoot.children.filter(function(s) { + return !s.hidden && !s.waypoints && (is(s, 'bpmn:FlowElement') || is(s, 'bpmn:Artifact')); + }); + + flowElements.forEach(function(flowElement) { + + var flowElementTrbl = asTRBL(flowElement); + + if (isFirst && /n/.test(resizeDirection)) { + addMin(minTrbl, 'top', flowElementTrbl.top - LANE_TOP_PADDING); + } + + if (/e/.test(resizeDirection)) { + addMax(minTrbl, 'right', flowElementTrbl.right + LANE_RIGHT_PADDING); + } + + if (isLast && /s/.test(resizeDirection)) { + addMax(minTrbl, 'bottom', flowElementTrbl.bottom + LANE_BOTTOM_PADDING); + } + + if (/w/.test(resizeDirection)) { + addMin(minTrbl, 'left', flowElementTrbl.left - LANE_LEFT_PADDING); + } + }); + + + return { + min: minTrbl, + max: maxTrbl + }; +} + + +module.exports.getParticipantSizeConstraints = getParticipantSizeConstraints; \ No newline at end of file diff --git a/test/spec/features/snapping/BpmnSnappingSpec.js b/test/spec/features/snapping/BpmnSnappingSpec.js index e6db5a0e..e8f0ed16 100644 --- a/test/spec/features/snapping/BpmnSnappingSpec.js +++ b/test/spec/features/snapping/BpmnSnappingSpec.js @@ -14,9 +14,18 @@ var coreModule = require('../../../../lib/core'), moveModule = require('diagram-js/lib/features/move'), rulesModule = require('../../../../lib/features/rules'); + describe('features/snapping - BpmnSnapping', function() { - var testModules = [ coreModule, snappingModule, modelingModule, createModule, rulesModule, moveModule ]; + var testModules = [ + coreModule, + snappingModule, + modelingModule, + createModule, + rulesModule, + moveModule + ]; + describe('on Boundary Events', function() { @@ -225,7 +234,13 @@ describe('features/snapping - BpmnSnapping', function() { var diagramXML = require('./BpmnSnapping.participant-resize.bpmn'); - var testResizeModules = [ coreModule, resizeModule, rulesModule, snappingModule ]; + var testResizeModules = [ + coreModule, + resizeModule, + modelingModule, + rulesModule, + snappingModule + ]; beforeEach(bootstrapModeler(diagramXML, { modules: testResizeModules })); @@ -238,7 +253,7 @@ describe('features/snapping - BpmnSnapping', function() { dragging.move(canvasEvent({ x: 0, y: 0 })); dragging.end(); - expect(participant.width).to.equal(497); + expect(participant.width).to.equal(482); expect(participant.height).to.equal(252); })); @@ -265,7 +280,7 @@ describe('features/snapping - BpmnSnapping', function() { dragging.end(); expect(participant.width).to.equal(300); - expect(participant.height).to.equal(150); + expect(participant.height).to.equal(60); })); @@ -278,7 +293,7 @@ describe('features/snapping - BpmnSnapping', function() { dragging.end(); expect(participant.width).to.equal(300); - expect(participant.height).to.equal(150); + expect(participant.height).to.equal(60); })); @@ -290,7 +305,7 @@ describe('features/snapping - BpmnSnapping', function() { dragging.move(canvasEvent({ x: 0, y: 0 })); dragging.end(); - expect(participant.width).to.equal(320); + expect(participant.width).to.equal(305); // snap to children rather than min dimensions expect(participant.height).to.equal(143); @@ -316,7 +331,13 @@ describe('features/snapping - BpmnSnapping', function() { var diagramXML = require('./BpmnSnapping.lanes-resize.bpmn'); - var testResizeModules = [ coreModule, resizeModule, rulesModule, snappingModule ]; + var testResizeModules = [ + coreModule, + resizeModule, + modelingModule, + rulesModule, + snappingModule + ]; beforeEach(bootstrapModeler(diagramXML, { modules: testResizeModules })); @@ -329,8 +350,8 @@ describe('features/snapping - BpmnSnapping', function() { dragging.move(canvasEvent({ x: 500, y: 500 })); dragging.end(); - expect(participant.width).to.equal(600); - expect(participant.height).to.equal(254); + expect(participant.width).to.equal(563); + expect(participant.height).to.equal(223); })); @@ -342,8 +363,8 @@ describe('features/snapping - BpmnSnapping', function() { dragging.move(canvasEvent({ x: -500, y: -500 })); dragging.end(); - expect(lane.width).to.equal(570); - expect(lane.height).to.equal(118); + expect(lane.width).to.equal(313); + expect(lane.height).to.equal(122); })); }); diff --git a/test/spec/features/snapping/BpmnSnappingUtil.lanes-flowNodes.bpmn b/test/spec/features/snapping/BpmnSnappingUtil.lanes-flowNodes.bpmn new file mode 100644 index 00000000..3bd9e20f --- /dev/null +++ b/test/spec/features/snapping/BpmnSnappingUtil.lanes-flowNodes.bpmn @@ -0,0 +1,83 @@ + + + + + + + + + + + Boundary + Task_Boundary + + + + + + Task + + + + SequenceFlow_From_Boundary + + + + SequenceFlow + + + + SequenceFlow_From_Boundary + SequenceFlow + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/spec/features/snapping/BpmnSnappingUtil.lanes.bpmn b/test/spec/features/snapping/BpmnSnappingUtil.lanes.bpmn new file mode 100644 index 00000000..d1fb7e2e --- /dev/null +++ b/test/spec/features/snapping/BpmnSnappingUtil.lanes.bpmn @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/spec/features/snapping/BpmnSnappingUtilSpec.js b/test/spec/features/snapping/BpmnSnappingUtilSpec.js new file mode 100644 index 00000000..56b03c67 --- /dev/null +++ b/test/spec/features/snapping/BpmnSnappingUtilSpec.js @@ -0,0 +1,286 @@ +'use strict'; + +var TestHelper = require('test/TestHelper'); + +/* global bootstrapModeler, inject */ + + +var getParticipantSizeConstraints = require('lib/features/snapping/BpmnSnappingUtil').getParticipantSizeConstraints; + +var coreModule = require('lib/core'); + +var LANE_MIN_HEIGHT = 60, + LANE_RIGHT_PADDING = 20, + LANE_LEFT_PADDING = 50, + LANE_TOP_PADDING = 20, + LANE_BOTTOM_PADDING = 20; + + +describe('features/snapping - BpmnSnappingUtil', function() { + + describe('#getParticipantSizeConstraints', function() { + + describe('lanes', function() { + + var diagramXML = require('./BpmnSnappingUtil.lanes.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: [ coreModule ] })); + + + it('resize participant (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + otherLaneShape = elementRegistry.get('Lane_B'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: otherLaneShape.y + LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('bottom lane (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_B'), + otherLaneShape = elementRegistry.get('Lane_B'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: otherLaneShape.y + LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('resize participant (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + otherLaneShape = elementRegistry.get('Nested_Lane_A'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('resize top lane (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_A'), + otherLaneShape = elementRegistry.get('Nested_Lane_A'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT + }, + max: {} + }); + + })); + + + it('resize middle lane (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Nested_Lane_B'), + aboveLaneShape = elementRegistry.get('Nested_Lane_A'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: resizeShape.y + resizeShape.height - LANE_MIN_HEIGHT + }, + max: { + top: aboveLaneShape.y + LANE_MIN_HEIGHT + } + }); + + })); + + + it('resize middle lane (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Nested_Lane_B'), + otherLaneShape = elementRegistry.get('Lane_B'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: resizeShape.y + LANE_MIN_HEIGHT + }, + max: { + bottom: otherLaneShape.y + otherLaneShape.height - LANE_MIN_HEIGHT + } + }); + + })); + + }); + + + describe('flowNodes', function() { + + var diagramXML = require('./BpmnSnappingUtil.lanes-flowNodes.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: [ coreModule ] })); + + + it('resize participant (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + taskShape = elementRegistry.get('Task'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: taskShape.y + taskShape.height + LANE_BOTTOM_PADDING + }, + max: {} + }); + + })); + + + it('bottom lane (S)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_B'), + taskShape = elementRegistry.get('Task'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 's'); + + // then + expect(sizeConstraints).to.eql({ + min: { + bottom: taskShape.y + taskShape.height + LANE_BOTTOM_PADDING + }, + max: {} + }); + + })); + + + it('resize participant (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Participant_Lane'), + taskShape = elementRegistry.get('Task_Boundary'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: taskShape.y - LANE_TOP_PADDING + }, + max: {} + }); + + })); + + + it('resize top lane (N)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_A'), + taskShape = elementRegistry.get('Task_Boundary'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 'n'); + + // then + expect(sizeConstraints).to.eql({ + min: { + top: taskShape.y - LANE_TOP_PADDING + }, + max: {} + }); + + })); + + + it('resize lane (W)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Nested_Lane_B'), + otherShape = elementRegistry.get('Boundary_label'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 'w'); + + // then + expect(sizeConstraints).to.eql({ + min: { + left: otherShape.x - LANE_LEFT_PADDING + }, + max: { } + }); + + })); + + + it('resize lane (E)', inject(function(elementRegistry) { + + // given + var resizeShape = elementRegistry.get('Lane_B'), + otherShape = elementRegistry.get('Task'); + + // when + var sizeConstraints = getParticipantSizeConstraints(resizeShape, 'e'); + + // then + expect(sizeConstraints).to.eql({ + min: { + right: otherShape.x + otherShape.width + LANE_RIGHT_PADDING + }, + max: { } + }); + + })); + + }); + + }); + +}); \ No newline at end of file