Skip to content

Commit

Permalink
feat(distribute-elements): use rules to determine if allowed
Browse files Browse the repository at this point in the history
  • Loading branch information
barmac committed Jul 5, 2022
1 parent 43d7ffd commit 7f4f047
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 44 deletions.
17 changes: 14 additions & 3 deletions lib/features/distribute-elements/DistributeElements.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
sortBy,
forEach
forEach,
isArray
} from 'min-dash';

var AXIS_DIMENSIONS = {
Expand All @@ -14,13 +15,23 @@ var THRESHOLD = 5;
/**
* Groups and filters elements and then trigger even distribution.
*/
export default function DistributeElements(modeling) {
export default function DistributeElements(modeling, rules) {
this._modeling = modeling;

this._filters = [];

this.registerFilter(function(elements) {
var allowed = rules.allowed('elements.distribute', { elements: elements });

if (isArray(allowed)) {
return allowed;
}

return allowed ? elements : [];
});
}

DistributeElements.$inject = [ 'modeling' ];
DistributeElements.$inject = [ 'modeling', 'rules' ];


/**
Expand Down
56 changes: 54 additions & 2 deletions test/spec/features/align-elements/AlignElementsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
inject
} from 'test/TestHelper';

import { sortBy } from 'min-dash';

import alignElementsModule from 'lib/features/align-elements';
import modelingModule from 'lib/features/modeling';
Expand Down Expand Up @@ -211,20 +212,71 @@ describe('features/align-elements', function() {
});


it('should respect rules', inject(function(alignElements, eventBus) {
it('should respect rules (false)', inject(function(alignElements, eventBus, testRules) {

// given
var changedSpy = sinon.spy();

eventBus.once('commandStack.changed', changedSpy);
eventBus.once('elements.changed', function(_, context) {
changedSpy(context.elements);
});

testRules.setResult(false);

// when
alignElements.trigger(elements, 'left');

// then
expect(changedSpy).not.to.have.been.called;
}));


it('should respect rules (true)', inject(function(alignElements, eventBus, testRules) {

// given
var changedSpy = sinon.spy();

eventBus.once('elements.changed', function(_, context) {
changedSpy(context.elements);
});

testRules.setResult(true);

// when
alignElements.trigger(elements, 'left');

// then
expect(changedSpy).to.have.been.calledOnce;
expectSameElements(changedSpy.firstCall.args[0], elements);
}));


it('should respect rules (array)', inject(function(alignElements, eventBus, testRules) {

// given
var changedSpy = sinon.spy();

eventBus.once('elements.changed', function(_, context) {
changedSpy(context.elements);
});

testRules.setResult([ shape1, shape2 ]);

// when
alignElements.trigger(elements, 'left');

// then
expect(changedSpy).to.have.been.calledOnce;
expectSameElements(changedSpy.firstCall.args[0], [ shape1, shape2 ]);
}));
});
});

});



// helper //////////////////////////////////////////////////////////////////////
function expectSameElements(arr1, arr2) {
expect(sortBy(arr1, 'id')).to.eql(sortBy(arr2, 'id'));
}
9 changes: 7 additions & 2 deletions test/spec/features/align-elements/rules/TestRules.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ inherits(TestRules, RuleProvider);


TestRules.prototype.init = function() {
var self = this;

this.addRule('elements.align', function(context) {
return false;
return self._result;
});
};
};

TestRules.prototype.setResult = function(result) {
this._result = result;
};
164 changes: 127 additions & 37 deletions test/spec/features/distribute-elements/DistributeElementsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import {
inject
} from 'test/TestHelper';

import { forEach } from 'min-dash';
import { forEach, sortBy } from 'min-dash';

import distributeElementsModule from 'lib/features/distribute-elements';
import modelingModule from 'lib/features/modeling';
import testRules from './rules';


function expectRanges(rangeGroups, expectedRanges) {
Expand Down Expand Up @@ -147,56 +148,63 @@ describe('features/distribute-elements', function() {
describe('integration', function() {
var rootShape, shape1, shape2, shape3, shape4, shape5, shapeBig;

beforeEach(inject(function(elementFactory, canvas) {
function createShapes() {
inject(function(elementFactory, canvas) {

rootShape = elementFactory.createRoot({
id: 'root'
});
rootShape = elementFactory.createRoot({
id: 'root'
});

canvas.setRootElement(rootShape);
canvas.setRootElement(rootShape);

shape1 = elementFactory.createShape({
id: 's1',
x: 100, y: 100, width: 100, height: 100
});
shape1 = elementFactory.createShape({
id: 's1',
x: 100, y: 100, width: 100, height: 100
});

canvas.addShape(shape1, rootShape);
canvas.addShape(shape1, rootShape);

shape2 = elementFactory.createShape({
id: 's2',
x: 250, y: 100, width: 100, height: 100
});
shape2 = elementFactory.createShape({
id: 's2',
x: 250, y: 100, width: 100, height: 100
});

canvas.addShape(shape2, rootShape);
canvas.addShape(shape2, rootShape);

shape3 = elementFactory.createShape({
id: 's3',
x: 325, y: 250, width: 100, height: 100
});
shape3 = elementFactory.createShape({
id: 's3',
x: 325, y: 250, width: 100, height: 100
});

canvas.addShape(shape3, rootShape);
canvas.addShape(shape3, rootShape);

shape4 = elementFactory.createShape({
id: 's4',
x: 600, y: 350, width: 100, height: 100
});
shape4 = elementFactory.createShape({
id: 's4',
x: 600, y: 350, width: 100, height: 100
});

canvas.addShape(shape4, rootShape);
canvas.addShape(shape4, rootShape);

shape5 = elementFactory.createShape({
id: 's5',
x: 650, y: 451, width: 100, height: 100
});
shape5 = elementFactory.createShape({
id: 's5',
x: 650, y: 451, width: 100, height: 100
});

canvas.addShape(shape5, rootShape);
canvas.addShape(shape5, rootShape);

shapeBig = elementFactory.createShape({
id: 'sBig',
x: 150, y: 400, width: 200, height: 200
});
shapeBig = elementFactory.createShape({
id: 'sBig',
x: 150, y: 400, width: 200, height: 200
});

canvas.addShape(shapeBig, rootShape);
}));
canvas.addShape(shapeBig, rootShape);
})();
}


beforeEach(function() {
createShapes();
});


it('should align shapes horizontally', inject(function(distributeElements) {
Expand Down Expand Up @@ -254,6 +262,88 @@ describe('features/distribute-elements', function() {
expect(shapeBig.y).to.equal(300);
}));


describe('rules', function() {

var elements;

beforeEach(bootstrapDiagram({
modules: [ distributeElementsModule, modelingModule, testRules ]
}));


beforeEach(function() {
createShapes();

elements = [ shape5, shape3, shape1, shape4, shape2, shapeBig ];
});


it('should respect rules (false)', inject(function(distributeElements, eventBus,testRules) {

// given
var changedSpy = sinon.spy();

eventBus.once('commandStack.changed', function(_, context) {
changedSpy(context.elements);
});

testRules.setResult(false);

// when
distributeElements.trigger(elements, 'horizontal');

// then
expect(changedSpy).not.to.have.been.called;
}));


it('should respect rules (true)', inject(function(distributeElements, eventBus, testRules) {

// given
var changedSpy = sinon.spy();

eventBus.once('elements.changed', function(_, context) {
changedSpy(context.elements);
});

testRules.setResult(true);

// when
distributeElements.trigger(elements, 'horizontal');

// then
expect(changedSpy).to.have.been.calledOnce;
expectSameElements(changedSpy.firstCall.args[0], [ shape2, shape3, shape4, shapeBig ]);
}));


it('should respect rules (array)', inject(function(distributeElements, eventBus, testRules) {

// given
var changedSpy = sinon.spy();

eventBus.once('elements.changed', function(_, context) {
changedSpy(context.elements);
});

testRules.setResult([ shape1, shape2, shape5 ]);

// when
distributeElements.trigger(elements, 'horizontal');

// then
expect(changedSpy).to.have.been.calledOnce;
expectSameElements(changedSpy.firstCall.args[0], [ shape2 ]);
}));
});
});

});



// helper //////////////////////////////////////////////////////////////////////
function expectSameElements(arr1, arr2) {
expect(sortBy(arr1, 'id')).to.eql(sortBy(arr2, 'id'));
}
24 changes: 24 additions & 0 deletions test/spec/features/distribute-elements/rules/TestRules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import inherits from 'inherits-browser';

import RuleProvider from 'lib/features/rules/RuleProvider';

export default function TestRules(eventBus) {
RuleProvider.call(this, eventBus);
}

TestRules.$inject = [ 'eventBus' ];

inherits(TestRules, RuleProvider);


TestRules.prototype.init = function() {
var self = this;

this.addRule('elements.distribute', function(context) {
return self._result;
});
};

TestRules.prototype.setResult = function(result) {
this._result = result;
};
6 changes: 6 additions & 0 deletions test/spec/features/distribute-elements/rules/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import TestRules from './TestRules';

export default {
__init__: [ 'testRules' ],
testRules: [ 'type', TestRules ]
};

0 comments on commit 7f4f047

Please sign in to comment.