Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor-actions): only copy if selected elements #660

Merged
merged 1 commit into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/features/editor-actions/EditorActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ EditorActions.prototype._registerDefaultActions = function(injector) {
this.register('copy', function() {
var selectedElements = selection.get();

copyPaste.copy(selectedElements);
if (selectedElements.length) {
return copyPaste.copy(selectedElements);
}
});
}

Expand Down
225 changes: 146 additions & 79 deletions test/spec/features/editor-actions/EditorActionsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
} from 'test/TestHelper';

import editorActionsModule from 'lib/features/editor-actions';
import copyPasteModule from 'lib/features/copy-paste';
import selectionModule from 'lib/features/selection';
import keyboardMoveModule from 'lib/navigation/keyboard-move';
import keyboardMoveSelectionModule from 'lib/features/keyboard-move-selection';
import modelingModule from 'lib/features/modeling';
Expand Down Expand Up @@ -204,129 +206,134 @@ describe('features/editor-actions', function() {

});

});

describe('actions', function() {

describe('removeSelection', function() {
describe('feature/editor-actions - actions', function() {

var selectedElements,
removeElements;
describe('removeSelection', function() {

beforeEach(inject(function(selection, modeling) {
selectedElements = [];
beforeEach(bootstrapDiagram({
modules: [
editorActionsModule,
modelingModule,
customRulesModule
]
}));

sinon.stub(selection, 'get').callsFake(function() {
return selectedElements;
});

removeElements = sinon.spy(modeling, 'removeElements');
}));
var selectedElements,
removeElements;

beforeEach(inject(function(selection, modeling) {
selectedElements = [];

it('should call modeling.removeElements with selected elements', inject(function(editorActions) {
selectedElements = [ 'any' ];
sinon.stub(selection, 'get').callsFake(function() {
return selectedElements;
});

// when
editorActions.trigger('removeSelection');
removeElements = sinon.spy(modeling, 'removeElements');
}));

// then
expect(removeElements).to.have.been.calledOnce;
expect(removeElements).to.have.been.calledWith(selectedElements);

// pass shalow copy of selection
expect(removeElements.getCall(0).args[0]).not.to.equal(selectedElements);
}));
it('should call modeling.removeElements with selected elements', inject(function(editorActions) {
selectedElements = [ 'any' ];

// when
editorActions.trigger('removeSelection');

it('should NOT call modeling.removeElements when no element is selected', inject(function(editorActions) {
selectedElements = [];
// then
expect(removeElements).to.have.been.calledOnce;
expect(removeElements).to.have.been.calledWith(selectedElements);

// when
editorActions.trigger('removeSelection');
// pass shallow copy of selection
expect(removeElements.getCall(0).args[0]).not.to.equal(selectedElements);
}));

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

it('should NOT call modeling.removeElements when no element is selected', inject(function(editorActions) {
selectedElements = [];

describe('with rules', function() {
// when
editorActions.trigger('removeSelection');

var RULE_NAME = 'elements.delete';
// then
expect(removeElements).not.to.have.been.called;
}));

it('should remove all when rule returns true', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];

customRules.addRule(RULE_NAME, function(context) {
return true;
});
describe('with rules', function() {

// when
editorActions.trigger('removeSelection');
var RULE_NAME = 'elements.delete';

// then
expect(removeElements).to.have.been.calledOnce;
expect(removeElements).to.have.been.calledWith([ 'a', 'b', 'c' ]);
}));
it('should remove all when rule returns true', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];

customRules.addRule(RULE_NAME, function(context) {
return true;
});

it('should not remove anything when rule returns true', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];
// when
editorActions.trigger('removeSelection');

customRules.addRule(RULE_NAME, function(context) {
return false;
});
// then
expect(removeElements).to.have.been.calledOnce;
expect(removeElements).to.have.been.calledWith([ 'a', 'b', 'c' ]);
}));

// when
editorActions.trigger('removeSelection');

// then
expect(removeElements).not.to.have.been.called;
}));
it('should not remove anything when rule returns true', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];

customRules.addRule(RULE_NAME, function(context) {
return false;
});

it('should only remove items returned by rule', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];
// when
editorActions.trigger('removeSelection');

customRules.addRule(RULE_NAME, function(context) {
return [ 'a', 'c' ];
});
// then
expect(removeElements).not.to.have.been.called;
}));

// when
editorActions.trigger('removeSelection');

// then
expect(removeElements).to.have.been.calledOnce;
expect(removeElements).to.have.been.calledWith([ 'a', 'c' ]);
}));
it('should only remove items returned by rule', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];

customRules.addRule(RULE_NAME, function(context) {
return [ 'a', 'c' ];
});

it('should call rule with .elements property', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];
// when
editorActions.trigger('removeSelection');

var ruleFn = sinon.spy(function(context) {
return true;
});
// then
expect(removeElements).to.have.been.calledOnce;
expect(removeElements).to.have.been.calledWith([ 'a', 'c' ]);
}));

customRules.addRule(RULE_NAME, ruleFn);

// when
editorActions.trigger('removeSelection');
it('should call rule with .elements property', inject(function(editorActions, customRules) {
selectedElements = [ 'a', 'b', 'c' ];

// then
expect(ruleFn).to.have.been.calledOnce;
expect(ruleFn).to.have.been.calledWith({ elements: [ 'a', 'b', 'c' ] });
}));
var ruleFn = sinon.spy(function(context) {
return true;
});

});
customRules.addRule(RULE_NAME, ruleFn);

});
// when
editorActions.trigger('removeSelection');

});
// then
expect(ruleFn).to.have.been.calledOnce;
expect(ruleFn).to.have.been.calledWith({ elements: [ 'a', 'b', 'c' ] });
}));

});
});

});

describe('feature/editor-actions - actions', function() {

describe('moveSelection', function() {

Expand Down Expand Up @@ -383,4 +390,64 @@ describe('feature/editor-actions - actions', function() {

});


describe('copy + paste', function() {

beforeEach(bootstrapDiagram({
modules: [
editorActionsModule,
copyPasteModule,
selectionModule,
modelingModule
]
}));


var root, shape;

beforeEach(inject(function(elementFactory, canvas) {
root = elementFactory.createRoot({
id: 'root'
});

canvas.setRootElement(root);

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

canvas.addShape(shape, root);
}));


it('should copy non empty', inject(function(selection, clipboard, editorActions) {

// given
selection.select(shape);

// when
var copied = editorActions.trigger('copy');

// then
expect(copied).to.exist;
expect(copied).to.equal(clipboard.get());
}));


it('should not copy empty', inject(function(selection, editorActions) {

// assume
expect(selection.get()).to.be.empty;

// when
var copied = editorActions.trigger('copy');

// then
expect(copied).not.to.exist;
}));

});

});