UNPKG

jointjs

Version:

JavaScript diagramming library

1,042 lines (831 loc) 58.1 kB
'use strict'; QUnit.module('linkView', function(hooks) { var paper; var link; var linkView; var link2; var linkView2; hooks.beforeEach(function() { paper = new joint.dia.Paper({ el: $('<div/>').appendTo('#qunit-fixture'), model: new joint.dia.Graph, width: 300, height: 300 }); link = new joint.dia.Link({ source: { x: 100, y: 100 }, target: { x: 200, y: 100 } }); link.addTo(paper.model); linkView = link.findView(paper); link2 = new joint.dia.Link({ source: { x: 100, y: 100 }, target: { x: 100, y: 100 } }); link2.addTo(paper.model); linkView2 = link2.findView(paper); }); hooks.afterEach(function() { paper.remove(); paper = null; }); QUnit.module('labels', function() { QUnit.test('SVGGroup container', function(assert) { link.labels([{}]); assert.ok(linkView.el.querySelector('.labels')); link.labels([]); assert.notOk(linkView.el.querySelector('.labels')); }); QUnit.test('Selectors', function(assert) { link.labels([{ 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 rootNode = linkView.el.querySelector('[root-test]'); var circleNode = linkView.el.querySelector('[circle-test]'); var rectNode = linkView.el.querySelector('[rect-test]'); var group = linkView.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('addLabel', function(hooks) { QUnit.test('default args', function(assert) { linkView.addLabel(100, 100); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0, offset: 0 }}); link.removeLabel(0); linkView.addLabel(150, 100); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0.5, offset: 0 }}); link.removeLabel(0); linkView.addLabel(200, 100); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: 0 }}); link.removeLabel(0); linkView.addLabel(175, 50); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0.75, offset: -50 }}); link.removeLabel(0); linkView.addLabel(250, 100); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: 0 }}); link.removeLabel(0); linkView2.addLabel(100, 100); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 0, y: 0 }}}); link2.removeLabel(0); linkView2.addLabel(150, 50); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 50, y: -50 }}}); link2.removeLabel(0); }); QUnit.test('absolute distance', function(assert) { linkView.addLabel(100, 100, { absoluteDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0, offset: 0, args: { absoluteDistance: true }}}); link.removeLabel(0); linkView.addLabel(150, 100, { absoluteDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 50, offset: 0, args: { absoluteDistance: true }}}); link.removeLabel(0); linkView.addLabel(200, 100, { absoluteDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 100, offset: 0, args: { absoluteDistance: true }}}); link.removeLabel(0); linkView.addLabel(175, 50, { absoluteDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 75, offset: -50, args: { absoluteDistance: true }}}); link.removeLabel(0); linkView.addLabel(250, 100, { absoluteDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 100, offset: 0, args: { absoluteDistance: true }}}); link.removeLabel(0); linkView2.addLabel(100, 100, { absoluteDistance: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { absoluteDistance: true }}}); link2.removeLabel(0); linkView2.addLabel(150, 50, { absoluteDistance: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 50, y: -50 }, args: { absoluteDistance: true }}}); link2.removeLabel(0); }); QUnit.test('reverse distance', function(assert) { linkView.addLabel(100, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: -100, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(150, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: -50, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(200, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(175, 50, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: -25, offset: -50, args: { absoluteDistance: true, reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(250, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}}); link.removeLabel(0); linkView2.addLabel(100, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true }}}); link2.removeLabel(0); linkView2.addLabel(150, 50, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 1, offset: { x: 50, y: -50 }, args: { absoluteDistance: true, reverseDistance: true }}}); link2.removeLabel(0); }); QUnit.test('reverse distance without absolute distance (no effect)', function(assert) { linkView.addLabel(100, 100, { reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0, offset: 0, args: { reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(150, 100, { reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0.5, offset: 0, args: { reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(200, 100, { reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: 0, args: { reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(175, 50, { reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0.75, offset: -50, args: { reverseDistance: true }}}); link.removeLabel(0); linkView.addLabel(250, 100, { reverseDistance: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: 0, args: { reverseDistance: true }}}); link.removeLabel(0); linkView2.addLabel(100, 100, { reverseDistance: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { reverseDistance: true }}}); link2.removeLabel(0); linkView2.addLabel(150, 50, { reverseDistance: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 50, y: -50 }, args: { reverseDistance: true }}}); link2.removeLabel(0); }); QUnit.test('absolute offset', function(assert) { linkView.addLabel(100, 100, { absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(150, 100, { absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0.5, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(200, 100, { absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(175, 50, { absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 0.75, offset: { x: 0, y: -50 }, args: { absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(250, 100, { absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: { x: 50, y: 0 }, args: { absoluteOffset: true }}}); link.removeLabel(0); linkView2.addLabel(100, 100, { absoluteOffset: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}}); link2.removeLabel(0); linkView2.addLabel(150, 50, { absoluteOffset: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 0, offset: { x: 50, y: -50 }, args: { absoluteOffset: true }}}); link2.removeLabel(0); }); QUnit.test('all args', function(assert) { linkView.addLabel(100, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: -100, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(150, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: -50, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(200, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(175, 50, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: -25, offset: { x: 0, y: -50 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}}); link.removeLabel(0); linkView.addLabel(250, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(link.label(0), { position: { angle: 0, distance: 1, offset: { x: 50, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}}); link.removeLabel(0); linkView2.addLabel(100, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}}); link2.removeLabel(0); linkView2.addLabel(150, 50, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(link2.label(0), { position: { angle: 0, distance: 1, offset: { x: 50, y: -50 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}}); link2.removeLabel(0); }); }); QUnit.module('addVertex', function(hooks) { QUnit.test('add vertex', function(assert) { assert.deepEqual(link.vertices(), []); linkView.addVertex(150, 100); assert.deepEqual(link.vertices(), [{ x: 150, y: 100 }]); linkView.addVertex(175, 50); assert.deepEqual(link.vertices(), [{ x: 150, y: 100 }, { x: 175, y: 50 }]); linkView.addVertex(250, 100); assert.deepEqual(link.vertices(), [{ x: 150, y: 100 }, { x: 175, y: 50 }, { x: 250, y: 100 }]); linkView.addVertex(150, 50); assert.deepEqual(link.vertices(), [{ x: 150, y: 100 }, { x: 150, y: 50 }, { x: 175, y: 50 }, { x: 250, y: 100 }]); }); }); QUnit.module('findLabelNode', function(hooks) { QUnit.test('root', function(assert) { link.labels([{ }, { }]); assert.equal(linkView.findLabelNode(0).getAttribute('label-idx'), '0'); assert.equal(linkView.findLabelNode(1).getAttribute('label-idx'), '1'); assert.equal(linkView.findLabelNode(2), null); }); QUnit.test('by selector', function(assert) { link.labels([{ }, { }]); var rect0 = linkView.findLabelNode(0, 'rect'); assert.ok(rect0 instanceof SVGRectElement); assert.equal(rect0.parentNode.getAttribute('label-idx'), '0'); var text1 = linkView.findLabelNode(1, 'text'); assert.ok(text1 instanceof SVGTextElement); assert.equal(text1.parentNode.getAttribute('label-idx'), '1'); // Edge Cases assert.equal(linkView.findLabelNode(1, 'invalid-selector'), null); assert.equal(linkView.findLabelNode(2, 'rect'), null); }); }); QUnit.module('getLabelPosition', function(hooks) { QUnit.test('default args', function(assert) { var labelPosition; labelPosition = linkView.getLabelPosition(100, 100); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: 0 }); labelPosition = linkView.getLabelPosition(150, 100); assert.deepEqual(labelPosition, { angle: 0, distance: 0.5, offset: 0 }); link.removeLabel(0); labelPosition = linkView.getLabelPosition(200, 100); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: 0 }); link.removeLabel(0); labelPosition = linkView.getLabelPosition(175, 50); assert.deepEqual(labelPosition, { angle: 0, distance: 0.75, offset: -50 }); link.removeLabel(0); labelPosition = linkView.getLabelPosition(250, 100); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: 0 }); link.removeLabel(0); labelPosition = linkView2.getLabelPosition(100, 100); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 0, y: 0 }}); link2.removeLabel(0); labelPosition = linkView2.getLabelPosition(150, 50); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 50, y: -50 }}); link2.removeLabel(0); }); QUnit.test('absolute distance', function(assert) { var labelPosition; labelPosition = linkView.getLabelPosition(100, 100, { absoluteDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: 0, args: { absoluteDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(150, 100, { absoluteDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 50, offset: 0, args: { absoluteDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(200, 100, { absoluteDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 100, offset: 0, args: { absoluteDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(175, 50, { absoluteDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 75, offset: -50, args: { absoluteDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(250, 100, { absoluteDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 100, offset: 0, args: { absoluteDistance: true }}); link.removeLabel(0); labelPosition = linkView2.getLabelPosition(100, 100, { absoluteDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { absoluteDistance: true }}); link2.removeLabel(0); labelPosition = linkView2.getLabelPosition(150, 50, { absoluteDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 50, y: -50 }, args: { absoluteDistance: true }}); link2.removeLabel(0); }); QUnit.test('reverse distance', function(assert) { var labelPosition; labelPosition = linkView.getLabelPosition(100, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: -100, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(150, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: -50, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(200, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(175, 50, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: -25, offset: -50, args: { absoluteDistance: true, reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(250, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: 0, args: { absoluteDistance: true, reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView2.getLabelPosition(100, 100, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true }}); link2.removeLabel(0); labelPosition = linkView2.getLabelPosition(150, 50, { absoluteDistance: true, reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 50, y: -50 }, args: { absoluteDistance: true, reverseDistance: true }}); link2.removeLabel(0); }); QUnit.test('reverse distance without absolute distance (no effect)', function(assert) { var labelPosition; labelPosition = linkView.getLabelPosition(100, 100, { reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: 0, args: { reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(150, 100, { reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0.5, offset: 0, args: { reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(200, 100, { reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: 0, args: { reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(175, 50, { reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0.75, offset: -50, args: { reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(250, 100, { reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: 0, args: { reverseDistance: true }}); link.removeLabel(0); labelPosition = linkView2.getLabelPosition(100, 100, { reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { reverseDistance: true }}); link2.removeLabel(0); labelPosition = linkView2.getLabelPosition(150, 50, { reverseDistance: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 50, y: -50 }, args: { reverseDistance: true }}); link2.removeLabel(0); }); QUnit.test('absolute offset', function(assert) { var labelPosition; labelPosition = linkView.getLabelPosition(100, 100, { absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(150, 100, { absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0.5, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(200, 100, { absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(175, 50, { absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0.75, offset: { x: 0, y: -50 }, args: { absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(250, 100, { absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 50, y: 0 }, args: { absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView2.getLabelPosition(100, 100, { absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 0, y: 0 }, args: { absoluteOffset: true }}); link2.removeLabel(0); labelPosition = linkView2.getLabelPosition(150, 50, { absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 0, offset: { x: 50, y: -50 }, args: { absoluteOffset: true }}); link2.removeLabel(0); }); QUnit.test('all args', function(assert) { var labelPosition; labelPosition = linkView.getLabelPosition(100, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: -100, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(150, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: -50, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(200, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(175, 50, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: -25, offset: { x: 0, y: -50 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView.getLabelPosition(250, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 50, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}); link.removeLabel(0); labelPosition = linkView2.getLabelPosition(100, 100, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 0, y: 0 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}); link2.removeLabel(0); labelPosition = linkView2.getLabelPosition(150, 50, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); assert.deepEqual(labelPosition, { angle: 0, distance: 1, offset: { x: 50, y: -50 }, args: { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }}); link2.removeLabel(0); }); }); QUnit.module('getLabelCoordinates', function(hooks) { QUnit.test('default', function(assert) { var labelCoordinates; labelCoordinates = linkView.getLabelCoordinates({ distance: 0, offset: 0 }); assert.equal(labelCoordinates.toString(), '100@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 0.5, offset: 0 }); assert.equal(labelCoordinates.toString(), '150@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: 0 }); assert.equal(labelCoordinates.toString(), '200@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 0.75, offset: -50 }); assert.equal(labelCoordinates.toString(), '175@50'); // unreachable region /*labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: 0 }); assert.equal(labelCoordinates.toString(), '250@100');*/ labelCoordinates = linkView2.getLabelCoordinates({ distance: 0, offset: 0 }); assert.equal(labelCoordinates.toString(), '100@100'); // offset coerced to absolute /*labelCoordinates = linkView2.getLabelCoordinates({ distance: 0, offset: { x: 50, y: -50 } }); assert.equal(labelCoordinates.toString(), '150@50');*/ }); QUnit.test('absolute', function(assert) { var labelCoordinates; labelCoordinates = linkView.getLabelCoordinates({ distance: 0, offset: 0 }); assert.equal(labelCoordinates.toString(), '100@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 50, offset: 0 }); assert.equal(labelCoordinates.toString(), '150@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 100, offset: 0 }); assert.equal(labelCoordinates.toString(), '200@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 75, offset: -50 }); assert.equal(labelCoordinates.toString(), '175@50'); // unreachable region /*labelCoordinates = linkView.getLabelCoordinates({ distance: 100, offset: 0 }); assert.equal(labelCoordinates.toString(), '250@100');*/ labelCoordinates = linkView2.getLabelCoordinates({ distance: 0, offset: 0 }); assert.equal(labelCoordinates.toString(), '100@100'); // offset coerced to absolute /*labelCoordinates = linkView2.getLabelCoordinates({ distance: 0, offset: { x: 50, y: -50 } }); assert.equal(labelCoordinates.toString(), '150@50');*/ }); QUnit.test('reverse absolute', function(assert) { var labelCoordinates; labelCoordinates = linkView.getLabelCoordinates({ distance: -100, offset: 0 }); assert.equal(labelCoordinates.toString(), '100@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: -50, offset: 0 }); assert.equal(labelCoordinates.toString(), '150@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: 0 }); assert.equal(labelCoordinates.toString(), '200@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: -25, offset: -50 }); assert.equal(labelCoordinates.toString(), '175@50'); // unreachable region /*labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: 0 }); assert.equal(labelCoordinates.toString(), '250@100');*/ labelCoordinates = linkView2.getLabelCoordinates({ distance: 1, offset: 0 }); assert.equal(labelCoordinates.toString(), '100@100'); // offset coerced to absolute /*labelCoordinates = linkView2.getLabelCoordinates({ distance: 0, offset: { x: 50, y: -50 } }); assert.equal(labelCoordinates.toString(), '150@50');*/ }); QUnit.test('absolute offset', function(assert) { var labelCoordinates; labelCoordinates = linkView.getLabelCoordinates({ distance: 0, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '100@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 0.5, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '150@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '200@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 0.75, offset: { x: 0, y: -50 }}); assert.equal(labelCoordinates.toString(), '175@50'); labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: { x: 50, y: 0 }}); assert.equal(labelCoordinates.toString(), '250@100'); labelCoordinates = linkView2.getLabelCoordinates({ distance: 0, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '100@100'); labelCoordinates = linkView2.getLabelCoordinates({ distance: 0, offset: { x: 50, y: -50 }}); assert.equal(labelCoordinates.toString(), '150@50'); }); QUnit.test('all', function(assert) { var labelCoordinates; labelCoordinates = linkView.getLabelCoordinates({ distance: -100, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '100@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: -50, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '150@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '200@100'); labelCoordinates = linkView.getLabelCoordinates({ distance: -25, offset: { x: 0, y: -50 }}); assert.equal(labelCoordinates.toString(), '175@50'); labelCoordinates = linkView.getLabelCoordinates({ distance: 1, offset: { x: 50, y: 0 }}); assert.equal(labelCoordinates.toString(), '250@100'); labelCoordinates = linkView2.getLabelCoordinates({ distance: 1, offset: { x: 0, y: 0 }}); assert.equal(labelCoordinates.toString(), '100@100'); labelCoordinates = linkView2.getLabelCoordinates({ distance: 1, offset: { x: 50, y: -50 }}); assert.equal(labelCoordinates.toString(), '150@50'); }); }); QUnit.module('getVertexIndex', function(hooks) { QUnit.test('get vertex index', function(assert) { var vertexIndex; vertexIndex = linkView.getVertexIndex(150, 100); assert.equal(vertexIndex, 0); linkView.addVertex(150, 100); vertexIndex = linkView.getVertexIndex(175, 50); assert.equal(vertexIndex, 1); linkView.addVertex(175, 50); vertexIndex = linkView.getVertexIndex(250, 100); assert.equal(vertexIndex, 2); linkView.addVertex(250, 100); vertexIndex = linkView.getVertexIndex(150, 50); assert.equal(vertexIndex, 1); linkView.addVertex(150, 50); }); }); QUnit.module('linkAnchors', function() { QUnit.test('sanity', function(assert) { // Source Anchor var sourceAnchor = new g.Point(1, -1); var sourceAnchorSpy = joint.linkAnchors.test1 = sinon.spy(function() { return sourceAnchor; }); linkView.model.source(link2, { anchor: { name: 'test1', args: { testArg1: true } } }); assert.ok(sourceAnchorSpy.calledOnce); assert.ok(sourceAnchorSpy.calledWithExactly( linkView2, linkView2.el, sinon.match.instanceOf(g.Point), sinon.match({ testArg1: true }), 'source', linkView )); assert.ok(sourceAnchorSpy.calledOn(linkView)); assert.deepEqual(linkView.sourceBBox.toJSON(), (new g.Rect(sourceAnchor)).toJSON()); // // Target Anchor var targetAnchor = new g.Point(-1, 1); var targetAnchorSpy = joint.linkAnchors.test2 = sinon.spy(function() { return targetAnchor; }); linkView.model.target(link2, { anchor: { name: 'test2', args: { testArg2: true } } }); assert.ok(targetAnchorSpy.calledOnce); assert.ok(targetAnchorSpy.calledWithExactly( linkView2, linkView2.el, sinon.match.instanceOf(g.Point), sinon.match({ testArg2: true }), 'target', linkView )); assert.ok(targetAnchorSpy.calledOn(linkView)); assert.deepEqual(linkView.targetBBox.toJSON(), (new g.Rect(targetAnchor)).toJSON()); // // Changing target updates both anchors assert.ok(sourceAnchorSpy.calledTwice); // // Source Magnet sourceAnchorSpy.resetHistory(); var sourceMagnetAnchorSpy = joint.anchors.test1 = sinon.spy(function() { return sourceAnchor; }); linkView.model.prop('source/magnet', '.connection'); assert.ok(sourceAnchorSpy.notCalled); assert.ok(sourceMagnetAnchorSpy.calledWithExactly( linkView2, // eslint-disable-next-line no-undef linkView2.el.querySelector('.connection'), sinon.match(function(value) { return value instanceof SVGElement; }), // requires resolving sinon.match({ testArg1: true }), 'source', linkView )); assert.ok(sourceMagnetAnchorSpy.calledOnce); // // Target Magnet targetAnchorSpy.resetHistory(); var targetMagnetAnchorSpy = joint.anchors.test2 = sinon.spy(function() { return targetAnchor; }); linkView.model.prop('target/magnet', '.connection'); assert.ok(targetAnchorSpy.notCalled); assert.ok(targetMagnetAnchorSpy.calledWithExactly( linkView2, linkView2.el.querySelector('.connection'), sinon.match.instanceOf(g.Point), sinon.match({ testArg2: true }), 'target', linkView )); assert.ok(targetMagnetAnchorSpy.calledOnce); assert.ok(sourceAnchor.equals(linkView.sourceAnchor)); assert.ok(targetAnchor.equals(linkView.targetAnchor)); // // Link connected by source to a point does not use anchors sourceAnchorSpy.resetHistory(); sourceMagnetAnchorSpy.resetHistory(); linkView.model.removeProp('source/id'); assert.ok(sourceAnchorSpy.notCalled); assert.ok(sourceMagnetAnchorSpy.notCalled); // Link connected by target to a point does not use anchors targetAnchorSpy.resetHistory(); targetMagnetAnchorSpy.resetHistory(); linkView.model.removeProp('target/id'); assert.ok(targetAnchorSpy.notCalled); assert.ok(targetMagnetAnchorSpy.notCalled); }); QUnit.test('joint.linkAnchors - source', function(assert) { link2.source({ x: 100, y: 100 }); link2.target({ x: 200, y: 100 }); link.source({ x: 160, y: 200 }); // RATIO link.target(link2, { anchor: { name: 'connectionRatio', args: { ratio: 0.2 }}}); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 120, y: 100 }); //L ENGTH link.target(link2, { anchor: { name: 'connectionLength', args: { length: 40 }}}); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 140, y: 100 }); // CLOSEST link.target(link2, { anchor: { name: 'connectionClosest' }}); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 160, y: 100 }); // PERPENDICULAR link.target(link2, { anchor: { name: 'connectionPerpendicular', args: { fallbackAt: '30%' }}}); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 160, y: 100 }); link.source({ x: 0, y: 200 }); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 130, y: 100 }); link.target(link2, { anchor: { name: 'connectionPerpendicular', args: { fallbackAt: 40 }}}); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 140, y: 100 }); link.removeProp('target/anchor/args'); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 100, y: 100 }); link2.target({ x: 100, y: 300 }); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 100, y: 200 }); link.prop('target/anchor/args', { fixedAt: '40%' }); link.source(link2, { anchor: { name: 'connectionRatio', args: { ratio: 0.9 }}}); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 100, y: 280 }); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 100, y: 280 }); // perpendicular link.prop('target/priority', true); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 100, y: 280 }); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 100, y: 180 }); // fixedAt // Multiple intersections link2.target({ x: 200, y: 100 }); link2.vertices([{ x: 100, y: 300 }, { x: 200, y: 300 }]); link.source(link2, { anchor: { name: 'connectionPerpendicular' }}); link.target({ x: 0, y: 150 }); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 100, y: 150 }); }); QUnit.test('joint.linkAchors - target', function(assert) { link2.source({ x: 100, y: 100 }); link2.target({ x: 200, y: 100 }); link.target({ x: 160, y: 200 }); // RATIO link.source(link2, { anchor: { name: 'connectionRatio', args: { ratio: 0.2 }}}); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 120, y: 100 }); // LENGTH link.source(link2, { anchor: { name: 'connectionLength', args: { length: 40 }}}); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 140, y: 100 }); // CLOSEST link.source(link2, { anchor: { name: 'connectionClosest' }}); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 160, y: 100 }); // PERPENDICULAR link.source(link2, { anchor: { name: 'connectionPerpendicular', args: { fallbackAt: '30%' }}}); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 160, y: 100 }); link.target({ x: 0, y: 200 }); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 130, y: 100 }); link.source(link2, { anchor: { name: 'connectionPerpendicular', args: { fallbackAt: 40 }}}); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 140, y: 100 }); link.removeProp('source/anchor/args'); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 100, y: 100 }); link2.target({ x: 100, y: 300 }); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 100, y: 200 }); link.prop('source/anchor/args', { fixedAt: '40%' }); link.target(link2, { anchor: { name: 'connectionRatio', args: { ratio: 0.9 }}}); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 100, y: 180 }); // fixedAt assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 100, y: 280 }); link.prop('target/priority', true); assert.deepEqual(linkView.sourceAnchor.toJSON(), { x: 100, y: 280 }); // perpendicular assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 100, y: 280 }); // Multiple intersections link2.target({ x: 200, y: 100 }); link2.vertices([{ x: 100, y: 300 }, { x: 200, y: 300 }]); link.target(link2, { anchor: { name: 'connectionPerpendicular' }}); link.source({ x: 0, y: 150 }); assert.deepEqual(linkView.targetAnchor.toJSON(), { x: 100, y: 150 }); }); }); QUnit.module('anchors', function(hooks) { var r1, r2, rv1, rv2; hooks.beforeEach(function() { r1 = new joint.shapes.standard.Rectangle(); r2 = new joint.shapes.standard.Rectangle(); r1.addTo(paper.model); r2.addTo(paper.model); rv1 = r1.findView(paper); rv2 = r2.findView(paper); }); QUnit.test('sanity', function(assert) { // Source Anchor var sourceAnchor = new g.Point(1, -1); var sourceAnchorSpy = joint.anchors.test1 = sinon.spy(function() { return sourceAnchor; }); linkView.model.source(r1, { anchor: { name: 'test1', args: { testArg1: true } } }); assert.ok(sourceAnchorSpy.calledOnce); assert.ok(sourceAnchorSpy.calledWithExactly( rv1, rv1.el, sinon.match.instanceOf(g.Point), sinon.match({ testArg1: true }), 'source', linkView )); assert.ok(sourceAnchorSpy.calledOn(linkView)); // Target Anchor var targetAnchor = new g.Point(-1, 1); var targetAnchorSpy = joint.anchors.test2 = sinon.spy(function() { return targetAnchor; }); linkView.model.target({ id: r2.id, anchor: { name: 'test2', args: { testArg2: true }} }); assert.ok(targetAnchorSpy.calledOnce); assert.ok(targetAnchorSpy.calledWithExactly( rv2, rv2.el, sinon.match.instanceOf(g.Point), sinon.match({ testArg2: true }), 'target', linkView )); assert.ok(targetAnchorSpy.calledOn(linkView)); // Changing target updates both anchors assert.ok(sourceAnchorSpy.calledTwice); // Source Magnet sourceAnchorSpy.resetHistory(); linkView.model.prop('source/magnet', 'body'); assert.ok(sourceAnchorSpy.calledWithExactly( rv1, rv1.el.querySelector('rect'), sinon.match(function(value) { return value instanceof SVGElement; }), // requires resolving sinon.match({ testArg1: true }), 'source', linkView )); // Target Magnet targetAnchorSpy.resetHistory(); linkView.model.prop('target/magnet', 'body'); assert.ok(targetAnchorSpy.calledWithExactly( rv2, rv2.el.querySelector('rect'), sinon.match.instanceOf(g.Point), sinon.match({ testArg2: true }), 'target', linkView )); assert.ok(sourceAnchor.equals(linkView.sourceAnchor)); assert.ok(targetAnchor.equals(linkView.targetAnchor)); // Link connected by source to a point does not use anchors sourceAnchorSpy.resetHistory(); linkView.model.removeProp('source/id'); assert.ok(sourceAnchorSpy.notCalled); // Link connected by target to a point does not use anchors targetAnchorSpy.resetHistory(); linkView.model.removeProp('target/id'); assert.ok(targetAnchorSpy.notCalled); }); }); QUnit.module('connectionPoints', function() { var r1, r2, rv1, rv2; hooks.beforeEach(function() { r1 = new joint.shapes.standard.Rectangle(); r2 = new joint.shapes.standard.Rectangle(); r1.addTo(paper.model); r2.addTo(paper.model); rv1 = r1.findView(paper); rv2 = r2.findView(paper); }); QUnit.test('sanity', function(assert) { // Sourcer connectionPoint var sourcePoint = new g.Point(1, -1); var sourceConnectionPointSpy = joint.connectionPoints.test1 = sinon.spy(function() { return sourcePoint; }); linkView.model.source(r1, { connectionPoint: { name: 'test1', args: { testArg1: true } } }); assert.ok(sourceConnectionPointSpy.calledOnce); assert.ok(sourceConnectionPointSpy.calledWithExactly( sinon.match.instanceOf(g.Line), rv1, rv1.el, sinon.match({ testArg1: true }), 'source', linkView )); assert.ok(sourceConnectionPointSpy.calledOn(linkView)); // Target connectionPoint var targetPoint = new g.Point(-1, 1); var targetConnectionPointSpy = joint.connectionPoints.test2 = sinon.spy(function() { return targetPoint; }); linkView.model.target({ id: r2.id, connectionPoint: { name: 'test2', args: { testArg2: true }} }); assert.ok(targetConnectionPointSpy.calledOnce); assert.ok(targetConnectionPointSpy.calledWithExactly( sinon.match.instanceOf(g.Line), rv2, rv2.el, sinon.match({ testArg2: true }), 'target', linkView )); assert.ok(targetConnectionPointSpy.calledOn(linkView)); // Changing target updates both connectionPoints assert.ok(sourceConnectionPointSpy.calledTwice); // Source Magnet sourceConnectionPointSpy.resetHistory(); linkView.model.prop('source/magnet', 'body'); assert.ok(sourceConnectionPointSpy.calledWithExactly( sinon.match.instanceOf(g.Line), rv1, rv1.el.querySelector('rect'), sinon.match({ testArg1: true }), 'source', li