jointjs
Version:
JavaScript diagramming library
913 lines (692 loc) • 31.7 kB
JavaScript
QUnit.module('element ports', function() {
var Model = joint.dia.Element.extend({
markup: '<g class="rotatable"><g class="scalable"><rect class="rectangle"/></g><text/></g>',
portMarkup: '<circle class="circle-port" />',
defaults: _.defaultsDeep({
type: 'basic.Model'
}, joint.dia.Element.prototype.defaults)
});
var create = function(initialPorts) {
return new Model({
ports: initialPorts
});
};
QUnit.module('port collection operations', function() {
QUnit.test('simple getters/setters', function(assert) {
var shape = create();
assert.equal(shape.getPorts().length, 0);
var portDefinition = {
id: 'first'
};
shape.addPort(portDefinition);
assert.equal(shape.getPorts().length, 1);
var p2 = {
id: 'second'
};
var p3 = {
id: 'third'
};
shape.addPorts([p2, p3]);
assert.equal(shape.getPorts().length, 3);
assert.equal(shape.getPorts()[0].id, 'first');
});
QUnit.test('initial ports', function(assert) {
var shape = create({ items: [{ 'group': 'in' }] });
assert.equal(shape.getPorts().length, 1);
});
QUnit.test('addPorts', function(assert) {
var shape = create({ items: [{ group: 'in' }] });
var eventOrder = ['ports:add', 'change:ports', 'change'];
shape.on('all', function(eventName) {
assert.equal(eventName, eventOrder.shift());
});
shape.addPort({ id: 'a' });
assert.equal(shape.getPorts().length, 2);
assert.equal(shape.getPorts()[1].id, 'a');
assert.ok(typeof shape.getPorts()[0].id === 'string');
});
QUnit.test('insertPort by index', function(assert) {
var shape = create({ items: [{ group: 'in' }] });
var eventOrder = ['ports:add', 'change:ports', 'change'];
shape.on('all', function(eventName) {
assert.equal(eventName, eventOrder.shift());
});
shape.insertPort(0, { id: 'a' });
assert.equal(shape.getPorts().length, 2);
assert.equal(shape.getPorts()[0].id, 'a');
assert.ok(typeof shape.getPorts()[1].id === 'string');
});
QUnit.test('insertPort by port', function(assert) {
var shape = create({ items: [{ group: 'in' }] });
shape.insertPort(shape.getPorts()[0], { id: 'a' });
assert.equal(shape.getPorts().length, 2);
assert.equal(shape.getPorts()[0].id, 'a');
assert.ok(typeof shape.getPorts()[1].id === 'string');
});
QUnit.test('insertPort by id', function(assert) {
var shape = create({ items: [{ group: 'in' }] });
shape.insertPort(0, { id: 'a' });
shape.insertPort('a', { id: 'b' });
assert.equal(shape.getPorts().length, 3);
assert.equal(shape.getPorts()[0].id, 'b');
assert.equal(shape.getPorts()[1].id, 'a');
assert.ok(typeof shape.getPorts()[2].id === 'string');
});
QUnit.test('remove port - by object', function(assert) {
var shape = create({ items: [{ id: 'aaa', 'group': 'in' }, { id: 'xxx', 'group': 'in' }] });
var eventOrder = ['ports:remove', 'change:ports', 'change'];
shape.on('all', function(eventName) {
assert.equal(eventName, eventOrder.shift());
});
shape.removePort(shape.getPort('aaa'));
assert.equal(shape.getPorts().length, 1);
assert.equal(shape.getPorts()[0].id, 'xxx');
});
QUnit.test('remove port - by id', function(assert) {
var shape = create({ items: [{ id: 'aaa', 'group_id': 'in' }, { id: 'xxx', 'group_id': 'in' }] });
var eventOrder = ['ports:remove', 'change:ports', 'change'];
shape.on('all', function(eventName) {
assert.equal(eventName, eventOrder.shift());
});
shape.removePort('aaa');
assert.equal(shape.getPorts().length, 1);
assert.equal(shape.getPorts()[0].id, 'xxx');
});
QUnit.test('remove port - invalid reference - should not remove any port', function(assert) {
var shape = create({ items: [{ id: 'aaa', 'group_id': 'in' }, { id: 'xxx', 'group_id': 'in' }] });
shape.removePort();
assert.equal(shape.getPorts().length, 2);
shape.removePort('non-existing-port');
assert.equal(shape.getPorts().length, 2);
});
QUnit.test('removePorts', function(assert) {
var shape = create({ items: [
{ id: 'aaa', 'group_id': 'in' },
{ id: 'bbb', 'group_id': 'in' },
{ id: 'xxx', 'group_id': 'in' }
] });
var eventOrder = ['ports:remove', 'change:ports', 'change'];
shape.on('all', function(eventName) {
assert.equal(eventName, eventOrder.shift());
});
shape.removePorts([{ id: 'aaa' }, { id: 'bbb' }]);
assert.equal(shape.getPorts().length, 1);
assert.equal(shape.getPorts()[0].id, 'xxx');
});
QUnit.test('removePorts - invalid reference - should not remove them', function(assert) {
var shape = create({ items: [
{ id: 'aaa', 'group_id': 'in' },
{ id: 'bbb', 'group_id': 'in' },
{ id: 'xxx', 'group_id': 'in' }
] });
var eventOrder = ['ports:remove', 'change:ports', 'change'];
shape.on('all', function(eventName) {
assert.equal(eventName, eventOrder.shift());
});
shape.removePorts([{ id: 'aaa' }, { id: 'ddd' }]);
assert.equal(shape.getPorts().length, 2);
assert.equal(shape.getPorts()[0].id, 'bbb');
assert.equal(shape.getPorts()[1].id, 'xxx');
});
QUnit.test('removePorts - should remove all ports when only given options', function(assert) {
var shape = create({ items: [
{ id: 'aaa', 'group_id': 'in' },
{ id: 'bbb', 'group_id': 'in' },
{ id: 'xxx', 'group_id': 'in' }
] });
var eventOrder = ['ports:remove', 'change:ports', 'change'];
shape.on('all', function(eventName) {
assert.equal(eventName, eventOrder.shift());
});
shape.removePorts();
assert.equal(shape.getPorts().length, 0);
});
QUnit.test('getPortIndex', function(assert) {
var idObject = {};
var ports = [
{},
{ id: 'aaa', 'group_id': 'in' },
{ id: 'xxx', 'group_id': 'in' },
{ x: 'whatever' },
{ id: '' },
{ id: 0 },
{ id: false },
{ id: true },
{ id: idObject }
];
var shape = create({ items: ports });
assert.equal(shape.getPortIndex('xxx'), 2);
assert.equal(shape.getPortIndex(ports[1]), 1);
assert.equal(shape.getPortIndex(), -1);
assert.equal(shape.getPortIndex(null), -1);
assert.equal(shape.getPortIndex(undefined), -1);
assert.equal(shape.getPortIndex(''), 4);
assert.equal(shape.getPortIndex(0), 5);
assert.equal(shape.getPortIndex(false), 6);
assert.equal(shape.getPortIndex(true), 7);
assert.equal(shape.getPortIndex(idObject), -1);
});
QUnit.test('initialized with no ports', function(assert) {
var shape = create();
assert.equal(shape.getPorts().length, 0);
});
QUnit.module('ids', function() {
QUnit.test('duplicate id', function(assert) {
assert.throws(function() {
create({ items: [{ 'group_id': 'in' }, { id: 'a' }, { id: 'a' }] });
}, function(err) {
return err.toString().indexOf('duplicities') !== -1;
});
});
QUnit.test('duplicate id - add port', function(assert) {
var shape = create({ items: [{ id: 'a' }] });
assert.throws(function() {
shape.addPort({ id: 'a' });
}, function(err) {
return err.toString().indexOf('duplicities ') !== -1;
});
});
QUnit.test('duplicate id - add ports', function(assert) {
var shape = create({ items: [{ id: 'a' }] });
assert.throws(function() {
shape.addPorts([{ id: 'x' }, { id: 'x' }]);
}, function(err) {
return err.toString().indexOf('duplicities') !== -1;
});
});
QUnit.test('auto generated id', function(assert) {
var shape = create({ items: [{ 'group': 'in' }] });
assert.equal(shape.getPorts().length, 1);
assert.ok(shape.getPorts()[0].id !== undefined, 'normalized on initialization');
shape.addPort({ group: 'a' });
assert.equal(shape.getPorts().length, 2);
assert.ok(shape.getPorts()[1].id !== undefined);
});
});
});
QUnit.module('attributes and markup', function() {
QUnit.test('is rendered correctly', function(assert) {
var ports = [
{
id: 'fst',
markup: '<g class="firstport"><rect/><text class="text"/></g>',
attrs: {
'.text': {
fill: 'blue',
text: 'aaa'
}
}
},
{
id: 'snd',
attrs: {
'circle': {
fill: 'red'
}
}
}
];
var shape = create({ items: ports });
var shapeView = new joint.dia.ElementView({ model: shape });
var renderPortSpy = sinon.spy(shapeView, '_createPortElement');
shapeView.render();
assert.ok(renderPortSpy.calledTwice);
assert.equal(shapeView.$el.find('.joint-port').length, 2);
var fst = shapeView.$el.find('.firstport');
var rect = fst.find('rect');
var text = fst.find('.text');
assert.equal(fst.length, 1);
assert.equal(rect.length, 1);
assert.equal(text.length, 1);
assert.equal(text.attr('fill'), 'blue');
assert.equal(text.text(), 'aaa');
var snd = shapeView.$el.find('.joint-port').eq(1);
var sndPortShape = snd.children().eq(0);
assert.equal(snd.length, 1);
assert.equal(sndPortShape[0].tagName.toLowerCase(), $(shape.portMarkup)[0].tagName.toLowerCase());
assert.equal(sndPortShape.attr('fill'), 'red');
});
QUnit.test('render custom port markup', function(assert) {
var WithoutPorts = joint.dia.Element.extend({
markup: '<g class="rotatable"><g class="scalable"><rect class="rectangle"/></g><text/></g>',
portMarkup: '<circle class="custom-port-markup"/>',
defaults: _.defaultsDeep({ type: 'temp' }, joint.dia.Element.prototype.defaults)
});
var model = new WithoutPorts();
var shapeView = new joint.dia.ElementView({ model: model });
model.addPorts([{ id: 'a' }, { id: 'b', markup: '<rect class="custom-rect" />' }]);
shapeView.render();
assert.equal(shapeView.$el.find('.joint-port').length, 2, 'port wraps');
assert.equal(shapeView.$el.find('.custom-port-markup').length, 1);
assert.equal(shapeView.$el.find('.custom-port-markup').prop('tagName'), 'circle');
assert.equal(shapeView.$el.find('.custom-rect').length, 1);
assert.equal(shapeView.$el.find('.custom-rect').prop('tagName'), 'rect');
});
QUnit.test('Selectors', function(assert) {
var shape = create({
items: [{
markup: [{
tagName: 'circle',
selector: 'c',
groupSelector: 'cr'
}, {
tagName: 'rect',
selector: 'r',
groupSelector: 'cr'
}],
attrs: {
root: { rootTest: true },
c: { circleTest: true },
r: { rectTest: true },
cr: { groupTest: true }
}
}]
});
var shapeView = new joint.dia.ElementView({ model: shape });
shapeView.render();
var rootNode = shapeView.el.querySelector('[root-test]');
var circleNode = shapeView.el.querySelector('[circle-test]');
var rectNode = shapeView.el.querySelector('[rect-test]');
var group = shapeView.el.querySelectorAll('[group-test]');
assert.ok(rootNode instanceof SVGGElement);
assert.ok(circleNode instanceof SVGCircleElement);
assert.ok(rectNode instanceof SVGRectElement);
assert.equal(group.length, 2);
assert.equal(group[0], circleNode);
assert.equal(group[1], rectNode);
});
});
QUnit.module('port update', function() {
QUnit.test('remove port elements from DOM', function(assert) {
var element = create();
element.addPorts([{ id: 'a' }, { id: 'b' }]);
var view = new joint.dia.ElementView({ model: element });
view.render();
assert.equal(view.vel.find('.joint-port').length, 2);
view._removePorts();
assert.equal(view.vel.find('.joint-port').length, 0, 'ports elements removed');
});
});
QUnit.module('z - index', function(hooks) {
QUnit.module('evaluate from definition', function(hooks) {
QUnit.test('test name', function(assert) {
var shape = create({
groups: { 'a': { z: 0 }}
});
shape.addPorts([
{ z: 0 },
{ z: 'auto' },
{ z: undefined },
{ group: 'a' }
]);
var ports = shape._portSettingsData.getPorts();
assert.equal(ports[0].z, 0);
assert.equal(ports[1].z, 'auto');
assert.equal(ports[2].z, 'auto');
assert.equal(ports[3].z, 0);
});
});
QUnit.test('elements order with z-index', function(assert) {
var data = {
items: [
{ z: 7, id: '7' },
{ z: 6, id: '6' },
{ z: 5, id: '5' },
{ z: 4, id: '4' },
{ id: 'x' },
{ z: 3, id: '3' },
{ z: 2, id: '2' },
{ z: 1, id: '1' },
{ z: 0, id: '0-1' },
{ z: 0, id: '0-2' },
{ z: 0, id: '0-3' }
]
};
var shape = create(data);
var view = new joint.dia.ElementView({ model: shape }).render();
var nodes = view.$el.find('.rotatable').children();
// var result = [];
// _.each(nodes, function(n) {
// result.push($(n).find('[port]').attr('port'));
// });
// console.log(result);
var i = 0;
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '0-1', 'z index 0, 0nth node');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '0-2');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '0-3');
assert.ok(nodes.eq(i++).hasClass('scalable'));
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '1');
assert.equal(nodes.eq(i++)[0].tagName, 'text');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '2');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), 'x');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '3');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '4');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '5');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '6');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '7');
});
QUnit.test('elements order with z-index and without', function(assert) {
var data = {
items: [
{ id: '111' },
{ id: '1' },
{ id: '2' },
{ id: '0001' },
{ z: 20, id: 'z20' },
{ z: 30, id: 'z30' }
]
};
var shape = create(data);
var view = new joint.dia.ElementView({ model: shape }).render();
var nodes = view.$el.find('.rotatable').children();
// var result = [];
// _.each(nodes, function(n) {
// result.push($(n).find('[port]').attr('port'));
// });
// console.log(result);
var i = 0;
assert.ok(nodes.eq(i++).hasClass('scalable'));
assert.equal(nodes.eq(i++)[0].tagName, 'text');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '111');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '1');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '2');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), '0001');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), 'z20');
assert.equal(nodes.eq(i++).find('[port]').attr('port'), 'z30');
});
QUnit.test('elements order - no z-index defined', function(assert) {
var data = {
items: [
{ id: 'a' },
{ id: 'b' },
{ id: 'c' }
]
};
var shape = create(data);
var view = new joint.dia.ElementView({ model: shape }).render();
var nodes = view.$el.find('.rotatable').children();
assert.ok(nodes.eq(0).hasClass('scalable'));
assert.equal(nodes.eq(1)[0].tagName, 'text');
assert.equal(nodes.eq(2).find('[port]').attr('port'), 'a');
assert.equal(nodes.eq(3).find('[port]').attr('port'), 'b');
assert.equal(nodes.eq(4).find('[port]').attr('port'), 'c');
});
});
QUnit.module('port grouping', function() {
QUnit.test('resolve position args', function(assert) {
var data = {
groups: {
'a': {
position: {
name: 'right',
args: { x: 10, y: 11, angle: 12 }
},
label: {
position: {
name: 'lefts',
args: { x: 10, y: 20, angle: 30 }
}
}
}, 'b': {
position: 'top'
}
},
items: [
{
id: 'pa',
args: { y: 20 },
group: 'a'
},
{
id: 'pb',
args: { y: 20 },
group: 'b'
}
]
};
var shape = create(data);
new joint.dia.ElementView({ model: shape }).render();
var getPort = function(id) {
return _.find(shape._portSettingsData.ports, function(p) {
return p.id === id;
});
};
assert.equal(getPort('pa').position.name, 'right');
assert.equal(getPort('pa').position.args.y, 20);
assert.equal(getPort('pa').position.args.x, 10);
assert.equal(getPort('pb').position.name, 'top');
assert.equal(getPort('pb').position.args.y, 20);
});
QUnit.test('resolve port labels', function(assert) {
var data = {
groups: {
'a': {
label: {
position: {
name: 'right',
args: { ty: 20 }
}
}
}, 'b': {}
},
items: [
{ id: 'pa1', group: 'a', label: { position: { name: 'top', args: { tx: 11 }}}},
{ id: 'pa2', group: 'a' },
{ id: 'pb1', group: 'b', label: { position: { args: { tx: 11 }}}},
{ id: 'pb2', group: 'b' }
]
};
var shape = create(data);
new joint.dia.ElementView({ model: shape }).render();
var getPort = function(id) {
return _.find(shape._portSettingsData.ports, function(p) {
return p.id === id;
});
};
assert.equal(getPort('pa1').label.position.name, 'top', 'override group settings');
assert.equal(getPort('pa1').label.position.args.tx, 11);
assert.equal(getPort('pa1').label.position.args.ty, 20);
assert.equal(getPort('pa2').label.position.name, 'right', 'gets settings from group');
assert.equal(getPort('pb1').label.position.name, 'left', 'default settings, extra args');
assert.equal(getPort('pb1').label.position.args.tx, 11);
assert.equal(getPort('pb2').label.position.name, 'left', 'defaults - no settings on group, either on port label');
});
});
QUnit.module('port layout', function(hooks) {
QUnit.test('straight line layouts', function(assert) {
var elBBox = g.rect(0, 0, 100, 100);
var trans = joint.layout.Port.left([
{},
{},
{ dx: 20, dy: -15 },
{ y: 100, x: 100, angle: 45 }
], elBBox, {});
var delta = trans[1].y - trans[0].y;
assert.equal(trans[0].y + delta, trans[1].y);
assert.equal(trans[0].x, 0);
assert.equal(trans[0].angle, 0);
assert.equal(trans[2].x, 20);
assert.equal(trans[2].y, trans[1].y + delta - 15, 'offset y should be applied');
assert.equal(trans[2].angle, 0);
assert.equal(trans[3].angle, 45);
assert.equal(trans[3].y, 100, 'override y position');
assert.equal(trans[3].x, 100, 'override y position');
});
QUnit.test('circular layouts', function(assert) {
var elBBox = g.rect(0, 0, 100, 100);
var trans = joint.layout.Port.ellipseSpread([
{},
{ dr: 3, compensateRotation: true },
{ dx: 1, dy: 2, dr: 3 },
{ x: 100, y: 101, angle: 10 }
], elBBox, {});
assert.equal(Math.round(trans[1].angle), -270, 'rotation compensation applied');
assert.equal(trans[1].x, 100 + 3, 'dr is applied');
assert.equal(trans[1].y, 50);
// middle bottom
assert.equal(trans[2].x, 50 + 1, 'dx is applied');
assert.equal(trans[2].y, 100 + 2 + 3, 'dy, dr are applied');
assert.equal(trans[3].x, 100, 'x position overridden');
assert.equal(trans[3].y, 101, 'y position overridden');
assert.equal(trans[3].angle, 10, 'y position overridden');
});
});
QUnit.module('getPortsPositions', function() {
QUnit.test('ports positions can be retrieved even if element is not rendered yet', function(assert) {
var shape = create({
groups: {
'a': { position: 'left' }
},
items: [
{ id: 'one', group: 'a' },
{ id: 'two', group: 'a' },
{ id: 'three', group: 'a' }
]
}).set('size', { width: 5, height: 10 });
var portsPositions = shape.getPortsPositions('a');
assert.ok(portsPositions.one.y > 0);
assert.ok(portsPositions.one.y < portsPositions.two.y);
assert.ok(portsPositions.two.y < portsPositions.three.y);
});
});
QUnit.module('getGroupPorts', function() {
QUnit.test('return ports with given group', function(assert) {
var shape = create({
groups: {
a: { position: 'left' },
b: { position: 'right' }
},
items: [
{ id: 'one', group: 'a' },
{ id: 'two', group: 'b' },
{ id: 'three', group: 'b' },
{ id: 'four', group: 'b' }
]
});
var portsA = shape.getGroupPorts('a');
var portsB = shape.getGroupPorts('b');
assert.equal(portsA.length, 1);
assert.equal(portsB.length, 3);
assert.ok(portsA.every(function(port) { return port.group === 'a'; }));
assert.ok(portsB.every(function(port) { return port.group === 'b'; }));
});
});
QUnit.module('portProp', function() {
QUnit.test('set port properties', function(assert) {
var shape = create({
items: [
{ id: 'one', attrs: { '.body': { fill: 'red' }}}
]
});
shape.portProp('one', 'attrs/.body/fill-opacity', 1);
assert.equal(shape.prop('ports/items/0/attrs/.body/fill-opacity'), 1);
shape.portProp('one', 'attrs/.body', { fill: 'newcolor' });
assert.equal(shape.prop('ports/items/0/attrs/.body/fill'), 'newcolor');
shape.portProp('one', 'attrs/.body', {});
assert.equal(shape.prop('ports/items/0/attrs/.body/fill'), 'newcolor');
shape.portProp('one', { attrs: { '.body': { fill: 'black', x: 1 }}});
assert.equal(shape.prop('ports/items/0/attrs/.body/fill'), 'black');
assert.equal(shape.prop('ports/items/0/attrs/.body/x'), 1);
});
QUnit.test('get port properties', function(assert) {
var shape = create({
items: [
{ id: 'one', attrs: { '.body': { fill: 'red' }}}
]
});
var prop = shape.portProp('one', 'attrs/.body');
assert.equal(prop.fill, 'red');
prop = shape.portProp('one');
assert.ok(prop.id, 'red');
});
QUnit.test('set port props, path defined as an array', function(assert) {
var shape = create({
items: [
{ id: 'one' }
]
});
shape.portProp('one', ['array', 20], 'array item');
shape.portProp('one', ['object', '20'], 'object property');
assert.ok(_.isArray(shape.portProp('one', 'array')));
assert.equal(shape.portProp('one', 'array')[20], 'array item');
assert.ok(_.isPlainObject(shape.portProp('one', 'object')));
assert.equal(shape.portProp('one', 'object/20'), 'object property');
});
});
QUnit.module('event ports:add and ports:remove', function(hooks) {
QUnit.config.testTimeout = 5000;
QUnit.test('simple add', function(assert) {
var shape = create({ items: [{}] });
assert.expect(3);
assert.equal(shape.getPorts().length, 1);
var done = assert.async();
shape.on('ports:add', function(cell, ports) {
assert.equal(ports.length, 1);
assert.equal(ports[0].id, 'a');
done();
});
shape.addPort({ id: 'a' });
});
QUnit.test('rewrite', function(assert) {
var shape = create({ items: [{ id: 'a' }] });
assert.expect(5);
assert.equal(shape.getPorts().length, 1);
var eventAddDone = assert.async();
var eventRemoveDone = assert.async();
shape.on('ports:add', function(cell, ports) {
assert.equal(ports.length, 1);
assert.equal(ports[0].id, 'b');
eventAddDone();
});
shape.on('ports:remove', function(cell, ports) {
assert.equal(ports.length, 1);
assert.equal(ports[0].id, 'a');
eventRemoveDone();
});
shape.prop('ports/items', [{ id: 'b' }], { rewrite: true });
});
QUnit.test('change id', function(assert) {
var shape = create({ items: [{ id: 'a' }] });
assert.expect(5);
assert.equal(shape.getPorts().length, 1);
var eventAddDone = assert.async();
var eventRemoveDone = assert.async();
shape.on('ports:add', function(cell, ports) {
assert.equal(ports.length, 1);
assert.equal(ports[0].id, 'b');
eventAddDone();
});
shape.on('ports:remove', function(cell, ports) {
assert.equal(ports.length, 1);
assert.equal(ports[0].id, 'a');
eventRemoveDone();
});
shape.prop('ports/items/0/id', 'b');
});
QUnit.test('failed to add', function(assert) {
var shape = create({ items: [{ id: 'a' }, { id: 'b' }, { id: 'c' }] });
assert.expect(3);
assert.equal(shape.getPorts().length, 3);
var done = assert.async();
shape.on('ports:remove', function(cell, ports) {
assert.equal(ports.length, 1);
assert.equal(ports[0].id, 'a');
done();
});
shape.removePort('a');
});
QUnit.test('add multiple', function(assert) {
var shape = create({ items: [{ id: 'a' }, { id: 'b' }, { id: 'c' }] });
assert.expect(4);
assert.equal(shape.getPorts().length, 3);
var done = assert.async();
shape.on('ports:add', function(cell, ports) {
assert.equal(ports.length, 2);
assert.equal(ports[0].id, 'x');
assert.equal(ports[1].id, 'y');
done();
});
shape.addPorts([{ id: 'x' }, { id: 'y' }]);
});
});
});