jointjs
Version:
JavaScript diagramming library
1,155 lines (1,103 loc) • 64.3 kB
JavaScript
QUnit.module('joint.dia.Paper', function(hooks) {
var Paper = joint.dia.Paper;
var paper;
var paperEl;
var graph;
function cellNodesCount(paper) {
return V(paper.cells).children().length;
}
function addCells(graph) {
var rect1 = new joint.shapes.standard.Rectangle();
var rect2 = new joint.shapes.standard.Rectangle();
var link = new joint.shapes.standard.Link();
rect1.resize(100, 100);
rect2.resize(100, 100);
rect1.position(-100, -100);
rect2.position(100, 100);
link.source(rect1);
link.target(rect2);
link.vertices([{ x: 0, y: 300 }]);
rect1.addTo(graph);
rect2.addTo(graph);
link.addTo(graph);
}
hooks.beforeEach(function() {
var fixtureEl = document.getElementById('qunit-fixture') || document.createElement('div');
paperEl = document.createElement('div');
fixtureEl.id = 'qunit-fixture';
fixtureEl.appendChild(paperEl);
document.body.appendChild(fixtureEl);
graph = new joint.dia.Graph;
});
hooks.afterEach(function() {
if (paper) paper.remove();
graph = null;
paper = null;
paperEl = null;
});
QUnit.test('sanity', function(assert) {
paper = new Paper({ el: paperEl });
assert.ok(paper.svg.id);
});
QUnit.module('options', function() {
QUnit.test('cloning', function(assert) {
var protoOptions = Paper.prototype.options;
var protoDefaultAnchor = protoOptions.defaultAnchor;
paper = new Paper({
el: paperEl,
defaultConnector: function() { return new g.Path(); },
defaultAnchor: { name: 'test', args: { testArg: 1 }},
// defaultRouter
interactive: false,
highlighting: false
});
// overridden with a function
var options = paper.options;
assert.ok(typeof options.defaultConnector === 'function');
// overridden with an object
assert.notEqual(options.defaultAnchor, protoOptions.defaultAnchor);
options.defaultAnchor.args.testArg = 2;
assert.deepEqual(protoDefaultAnchor, protoOptions.defaultAnchor);
// default
assert.notEqual(options.defaultRouter, protoOptions.defaultRouter);
// boolean
assert.equal(options.interactive, false);
assert.equal(options.highlighting, false);
});
});
QUnit.module('async = FALSE', function(hooks) {
hooks.beforeEach(function() {
paper = new Paper({
el: paperEl,
model: graph,
async: false
});
});
QUnit.module('getContentArea() > options > useModelGeometry', function() {
QUnit.test('useModelGeometry = FALSE', function(assert) {
var area = paper.getContentArea();
assert.ok(area instanceof g.Rect);
assert.deepEqual(area.toJSON(), { x: 0, y: 0, width: 0, height: 0 });
paper.freeze();
addCells(graph);
area = paper.getContentArea();
assert.ok(area instanceof g.Rect);
assert.deepEqual(area.toJSON(), { x: 0, y: 0, width: 0, height: 0 });
paper.unfreeze();
area = paper.getContentArea();
assert.deepEqual(area.toJSON(), { x: -100, y: -100, width: 300, height: 400 });
});
QUnit.test('useModelGeometry = TRUE', function(assert) {
var area = paper.getContentArea({ useModelGeometry: true });
assert.ok(area instanceof g.Rect);
assert.deepEqual(area.toJSON(), { x: 0, y: 0, width: 0, height: 0 });
paper.freeze();
addCells(graph);
area = paper.getContentArea({ useModelGeometry: true });
assert.ok(area instanceof g.Rect);
assert.deepEqual(area.toJSON(), { x: -100, y: -100, width: 300, height: 400 });
paper.unfreeze();
area = paper.getContentArea({ useModelGeometry: true });
assert.deepEqual(area.toJSON(), { x: -100, y: -100, width: 300, height: 400 });
});
});
QUnit.module('fitToContent() > options', function() {
[{
name: '0@0 200x200',
grid: 1,
contentArea: {
x: 0,
y: 0,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 200,
height: 200
},
'any': {
x: 0,
y: 0,
width: 200,
height: 200
},
'negative': {
x: 0,
y: 0,
width: 200,
height: 200
},
'positive': {
x: 0,
y: 0,
width: 200,
height: 200,
}
}
}, {
name: '-200@-200 200x200',
grid: 1,
contentArea: {
x: -200,
y: -200,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 1,
height: 1
},
'any': {
x: -200,
y: -200,
width: 201,
height: 201
},
'negative': {
x: -200,
y: -200,
width: 201,
height: 201
},
'positive': {
x: 0,
y: 0,
width: 1,
height: 1,
}
}
}, {
name: '-200@-200 100x100',
grid: 1,
contentArea: {
x: -200,
y: -200,
width: 100,
height: 100
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 1,
height: 1
},
'any': {
x: -200,
y: -200,
width: 201,
height: 201
},
'negative': {
x: -200,
y: -200,
width: 201,
height: 201
},
'positive': {
x: 0,
y: 0,
width: 1,
height: 1,
}
}
}, {
name: '-200@-200 100x100, grid: 300',
grid: 300,
contentArea: {
x: -200,
y: -200,
width: 100,
height: 100
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 300,
height: 300
},
'any': {
x: -300,
y: -300,
width: 600,
height: 600
},
'negative': {
x: -300,
y: -300,
width: 600,
height: 600
},
'positive': {
x: 0,
y: 0,
width: 300,
height: 300
}
}
}, {
name: '-100@-100 200x200',
grid: 1,
contentArea: {
x: -100,
y: -100,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 100,
height: 100
},
'any': {
x: -100,
y: -100,
width: 200,
height: 200
},
'negative': {
x: -100,
y: -100,
width: 200,
height: 200
},
'positive': {
x: 0,
y: 0,
width: 100,
height: 100
}
}
}, {
name: '-100@-100 200x200, grid: 300',
grid: 300,
contentArea: {
x: -100,
y: -100,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 300,
height: 300
},
'any': {
x: -300,
y: -300,
width: 600,
height: 600
},
'negative': {
x: -300,
y: -300,
width: 600,
height: 600
},
'positive': {
x: 0,
y: 0,
width: 300,
height: 300
}
}
}, {
name: '200@200 100x100',
grid: 1,
contentArea: {
x: 200,
y: 200,
width: 100,
height: 100
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 300,
height: 300
},
'any': {
x: 200,
y: 200,
width: 100,
height: 100
},
'negative': {
x: 0,
y: 0,
width: 300,
height: 300
},
'positive': {
x: 200,
y: 200,
width: 100,
height: 100
}
}
}, {
name: '200@200 100x100',
grid: 150,
contentArea: {
x: 200,
y: 200,
width: 120,
height: 120
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 450,
height: 450
},
'any': {
x: 150,
y: 150,
width: 300,
height: 300
},
'negative': {
x: 0,
y: 0,
width: 450,
height: 450
},
'positive': {
x: 150,
y: 150,
width: 300,
height: 300
}
}
}].forEach(function(testCase) {
var expectedAreas = testCase.expectedAreas;
Object.keys(expectedAreas).forEach(function(origin) {
QUnit.test(testCase.name + ', origin: ' + origin, function(assert) {
var grid = testCase.grid;
var area = paper.fitToContent({
contentArea: testCase.contentArea,
allowNewOrigin: origin,
gridWidth: grid,
gridHeight: grid
});
var expectedArea = expectedAreas[origin];
assert.deepEqual(area.toJSON(), expectedArea, 'Result of paper.fitToContent()');
assert.deepEqual(paper.getArea().toJSON(), expectedArea, 'Result of paper.getArea()');
assert.equal(area.width % grid, 0, 'Width is multiple of grid');
assert.equal(area.height % grid, 0, 'Height is multiple of grid');
});
});
});
});
QUnit.module('fitToContent() > options > allowNegativeBottomRight = true', function() {
[{
name: '0@0 200x200',
grid: 1,
contentArea: {
x: 0,
y: 0,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 200,
height: 200
},
'any': {
x: 0,
y: 0,
width: 200,
height: 200
},
'negative': {
x: 0,
y: 0,
width: 200,
height: 200
},
'positive': {
x: 0,
y: 0,
width: 200,
height: 200,
}
}
}, {
name: '-200@-200 200x200',
grid: 1,
contentArea: {
x: -200,
y: -200,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 1,
height: 1
},
'any': {
x: -200,
y: -200,
width: 200,
height: 200
},
'negative': {
x: -200,
y: -200,
width: 200,
height: 200
},
'positive': {
x: 0,
y: 0,
width: 1,
height: 1,
}
}
}, {
name: '-200@-200 100x100',
grid: 1,
contentArea: {
x: -200,
y: -200,
width: 100,
height: 100
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 1,
height: 1
},
'any': {
x: -200,
y: -200,
width: 100,
height: 100
},
'negative': {
x: -200,
y: -200,
width: 100,
height: 100
},
'positive': {
x: 0,
y: 0,
width: 1,
height: 1,
}
}
}, {
name: '-200@-200 100x100, grid: 300',
grid: 300,
contentArea: {
x: -200,
y: -200,
width: 100,
height: 100
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 300,
height: 300
},
'any': {
x: -300,
y: -300,
width: 300,
height: 300
},
'negative': {
x: -300,
y: -300,
width: 300,
height: 300
},
'positive': {
x: 0,
y: 0,
width: 300,
height: 300
}
}
}, {
name: '-100@-100 200x200',
grid: 1,
contentArea: {
x: -100,
y: -100,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 100,
height: 100
},
'any': {
x: -100,
y: -100,
width: 200,
height: 200
},
'negative': {
x: -100,
y: -100,
width: 200,
height: 200
},
'positive': {
x: 0,
y: 0,
width: 100,
height: 100
}
}
}, {
name: '-100@-100 200x200, grid: 300',
grid: 300,
contentArea: {
x: -100,
y: -100,
width: 200,
height: 200
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 300,
height: 300
},
'any': {
x: -300,
y: -300,
width: 600,
height: 600
},
'negative': {
x: -300,
y: -300,
width: 600,
height: 600
},
'positive': {
x: 0,
y: 0,
width: 300,
height: 300
}
}
}, {
name: '200@200 100x100',
grid: 1,
contentArea: {
x: 200,
y: 200,
width: 100,
height: 100
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 300,
height: 300
},
'any': {
x: 200,
y: 200,
width: 100,
height: 100
},
'negative': {
x: 0,
y: 0,
width: 300,
height: 300
},
'positive': {
x: 200,
y: 200,
width: 100,
height: 100
}
}
}, {
name: '200@200 100x100',
grid: 150,
contentArea: {
x: 200,
y: 200,
width: 120,
height: 120
},
expectedAreas: {
'default': {
x: 0,
y: 0,
width: 450,
height: 450
},
'any': {
x: 150,
y: 150,
width: 300,
height: 300
},
'negative': {
x: 0,
y: 0,
width: 450,
height: 450
},
'positive': {
x: 150,
y: 150,
width: 300,
height: 300
}
}
}].forEach(function(testCase) {
var expectedAreas = testCase.expectedAreas;
Object.keys(expectedAreas).forEach(function(origin) {
QUnit.test(testCase.name + ', origin: ' + origin, function(assert) {
var grid = testCase.grid;
var area = paper.fitToContent({
contentArea: testCase.contentArea,
allowNewOrigin: origin,
allowNegativeBottomRight: true,
gridWidth: grid,
gridHeight: grid
});
var expectedArea = expectedAreas[origin];
assert.deepEqual(area.toJSON(), expectedArea, 'Result of paper.fitToContent()');
assert.deepEqual(paper.getArea().toJSON(), expectedArea, 'Result of paper.getArea()');
assert.equal(area.width % grid, 0, 'Width is multiple of grid');
assert.equal(area.height % grid, 0, 'Height is multiple of grid');
});
});
});
});
QUnit.module('fitToContent() > options > useModelGeometry', function() {
[0.5, 1, 2].forEach(function(scale) {
QUnit.test('scale = ' + scale + ' > useModelGeometry = TRUE', function(assert) {
paper.scale(scale);
//scale = 1;
var expected;
var area = paper.fitToContent({ useModelGeometry: true });
assert.ok(area instanceof g.Rect);
expected = {
x: 0,
y: 0,
width: 1 / scale,
height: 1 / scale
};
assert.deepEqual(area.toJSON(), expected);
assert.deepEqual(paper.getArea().toJSON(), expected);
addCells(graph);
area = paper.fitToContent({ useModelGeometry: true });
expected = {
x: 0,
y: 0,
width: 200,
height: 300
};
assert.deepEqual(area.toJSON(), expected);
assert.deepEqual(paper.getArea().toJSON(), expected);
area = paper.fitToContent({ useModelGeometry: true, allowNewOrigin: 'any' });
expected = {
x: -100,
y: -100,
width: 300,
height: 400
};
assert.deepEqual(area.toJSON(), expected);
assert.deepEqual(paper.getArea().toJSON(), expected);
var padding = 20;
area = paper.fitToContent({ useModelGeometry: true, allowNewOrigin: 'any', padding: padding });
expected = {
x: -100 - padding / scale,
y: - 100 - padding / scale,
width: 300 + 2 * padding / scale,
height: 400 + 2 * padding / scale
};
assert.deepEqual(area.toJSON(), expected);
assert.deepEqual(paper.getArea().toJSON(), expected);
});
});
});
Object.keys(Paper.sorting).forEach(function(sortingType) {
QUnit.module('sorting = ' + sortingType, function(hooks) {
hooks.beforeEach(function() {
paper.options.sorting = Paper.sorting[sortingType];
});
QUnit.module('options', function() {
QUnit.module('sorting', function() {
QUnit.test('sanity', function(assert) {
var rect1 = new joint.shapes.standard.Rectangle({ z: 0 });
var rect2 = new joint.shapes.standard.Rectangle({ z: 2 });
var rect3 = new joint.shapes.standard.Rectangle({ z: 1 });
var sortViewsExactSpy = sinon.spy(paper, 'sortViewsExact');
// RESET CELLS
graph.resetCells([rect1, rect2, rect3]);
var rect1View = rect1.findView(paper);
var rect2View = rect2.findView(paper);
var rect3View = rect3.findView(paper);
assert.equal(rect1View.el.previousElementSibling, null);
assert.equal(rect2View.el.previousElementSibling, rect3View.el);
assert.equal(rect3View.el.previousElementSibling, rect1View.el);
assert.equal(sortViewsExactSpy.callCount, paper.options.sorting === Paper.sorting.EXACT ? 1 : 0);
// CHANGE Z
rect3.toFront();
assert.equal(sortViewsExactSpy.callCount, paper.options.sorting === Paper.sorting.EXACT ? 2 : 0);
if (paper.options.sorting === Paper.sorting.NONE) {
assert.equal(rect1View.el.previousElementSibling, null);
assert.equal(rect2View.el.previousElementSibling, rect3View.el);
assert.equal(rect3View.el.previousElementSibling, rect1View.el);
} else {
assert.equal(rect1View.el.previousElementSibling, null);
assert.equal(rect2View.el.previousElementSibling, rect1View.el);
assert.equal(rect3View.el.previousElementSibling, rect2View.el);
}
sortViewsExactSpy.resetHistory();
rect3.translate(10, 10);
assert.ok(sortViewsExactSpy.notCalled);
// ADD CELLS
graph.clear();
graph.addCells([rect1, rect2, rect3]);
assert.equal(sortViewsExactSpy.callCount, paper.options.sorting === Paper.sorting.EXACT ? 1 : 0);
if (paper.options.sorting !== Paper.sorting.NONE) {
rect1View = rect1.findView(paper);
rect2View = rect2.findView(paper);
rect3View = rect3.findView(paper);
assert.equal(rect1View.el.previousElementSibling, null);
assert.equal(rect2View.el.previousElementSibling, rect1View.el);
assert.equal(rect3View.el.previousElementSibling, rect2View.el);
}
});
QUnit.test('frozen', function(assert) {
paper.freeze();
var rect1 = new joint.shapes.standard.Rectangle({ z: 0 });
var rect2 = new joint.shapes.standard.Rectangle({ z: 2 });
var rect3 = new joint.shapes.standard.Rectangle({ z: 1 });
var sortViewsExactSpy = sinon.spy(paper, 'sortViewsExact');
graph.resetCells([rect1, rect2, rect3]);
var rect1View = rect1.findView(paper);
var rect2View = rect2.findView(paper);
var rect3View = rect3.findView(paper);
rect3.toFront();
assert.ok(sortViewsExactSpy.notCalled);
paper.unfreeze();
assert.equal(sortViewsExactSpy.callCount, paper.options.sorting === Paper.sorting.EXACT ? 1 : 0);
if (paper.options.sorting !== Paper.sorting.NONE) {
assert.equal(rect1View.el.previousElementSibling, null);
assert.equal(rect2View.el.previousElementSibling, rect1View.el);
assert.equal(rect3View.el.previousElementSibling, rect2View.el);
}
sortViewsExactSpy.resetHistory();
paper.freeze();
rect3.translate(10, 10);
paper.unfreeze();
assert.ok(sortViewsExactSpy.notCalled);
});
});
QUnit.module('viewport', function() {
QUnit.test('sanity', function(assert) {
var visible = true;
var viewportSpy = sinon.spy(function() { return visible; });
paper.options.viewport = viewportSpy;
var rect = new joint.shapes.standard.Rectangle();
rect.addTo(graph);
var rectView = rect.findView(paper);
assert.ok(viewportSpy.calledOnce);
// 1. view is not mounted yet (not rendered)
assert.ok(viewportSpy.calledWithExactly(rectView, false, paper));
assert.ok(viewportSpy.calledOn(paper));
assert.equal(rectView.el.parentNode, paper.cells);
viewportSpy.resetHistory();
visible = false;
rect.translate(10, 0);
assert.ok(viewportSpy.calledOnce);
// 2. view was already mounted in step 1.
assert.ok(viewportSpy.calledWithExactly(rectView, true, paper));
viewportSpy.resetHistory();
rect.translate(10, 0);
assert.ok(viewportSpy.calledOnce);
// 3. view was unmounted in step 2.
assert.ok(viewportSpy.calledWithExactly(rectView, false, paper));
assert.notOk(rectView.el.parentNode);
});
});
QUnit.module('onViewUpdate', function() {
QUnit.test('sanity', function(assert) {
var onViewUpdateSpy = sinon.spy();
paper.options.onViewUpdate = onViewUpdateSpy;
var rect = new joint.shapes.standard.Rectangle();
rect.addTo(graph, { test1: true });
var rectView = rect.findView(paper);
assert.ok(onViewUpdateSpy.calledOnce);
assert.ok(onViewUpdateSpy.calledWithExactly(rectView, sinon.match.number, sinon.match.number, sinon.match({ test1: true }), paper));
assert.ok(onViewUpdateSpy.calledOn(paper));
onViewUpdateSpy.resetHistory();
rect.translate(10, 0, { test2: true });
assert.ok(onViewUpdateSpy.calledOnce);
assert.ok(onViewUpdateSpy.calledWithExactly(rectView, sinon.match.number, sinon.match.number, sinon.match({ test2: true }), paper));
});
QUnit.test('update connected links', function(assert) {
var rect1 = new joint.shapes.standard.Rectangle();
var rect2 = new joint.shapes.standard.Rectangle();
var link1 = new joint.shapes.standard.Link();
var link2 = new joint.shapes.standard.Link();
link1.source(rect1);
link1.target(rect2);
link2.target(link1);
rect1.addTo(graph);
rect2.addTo(graph);
link1.addTo(graph);
link2.addTo(graph);
var onViewUpdateSpy = sinon.spy(paper.options, 'onViewUpdate');
rect1.translate(10, 0, { test: true });
assert.ok(onViewUpdateSpy.calledThrice);
assert.ok(onViewUpdateSpy.calledWithExactly(link1.findView(paper), sinon.match.number, sinon.match.number, sinon.match({ test: true }), paper));
assert.ok(onViewUpdateSpy.calledWithExactly(link2.findView(paper), sinon.match.number, sinon.match.number, sinon.match({ test: true }), paper));
assert.ok(onViewUpdateSpy.calledWithExactly(rect1.findView(paper), sinon.match.number, sinon.match.number, sinon.match({ test: true }), paper));
});
QUnit.test('update cycled links', function(assert) {
var link1 = new joint.shapes.standard.Link();
var link2 = new joint.shapes.standard.Link();
link1.source(link2);
link2.source(link1);
paper.freeze();
link1.addTo(graph);
link2.addTo(graph);
paper.unfreeze();
var onViewUpdateSpy = sinon.spy(paper.options, 'onViewUpdate');
var confirmUpdateSpy = sinon.spy(joint.dia.LinkView.prototype, 'confirmUpdate');
// This will trigger onViewUpdate thrice (link1 attrs, link2 source/target, link1 source/target)
link1.attr('line/stroke', 'red', { test: true });
assert.ok(onViewUpdateSpy.calledThrice);
assert.ok(onViewUpdateSpy.calledWithExactly(link1.findView(paper), sinon.match.number, sinon.match.number, sinon.match({ test: true }), paper));
assert.ok(onViewUpdateSpy.calledWithExactly(link2.findView(paper), sinon.match.number, sinon.match.number, sinon.match({ test: true }), paper));
assert.ok(confirmUpdateSpy.calledTwice);
onViewUpdateSpy.restore();
confirmUpdateSpy.restore();
});
});
QUnit.module('onViewPostponed', function() {
QUnit.test('sanity', function(assert) {
var leftoverFlag = 1;
var onViewPostponedSpy = sinon.spy(function() {
leftoverFlag = 0;
return true;
});
paper.options.onViewPostponed = onViewPostponedSpy;
paper.options.elementView = joint.dia.ElementView.extend({
confirmUpdate: function() {
return leftoverFlag;
}
});
var rect = new joint.shapes.standard.Rectangle();
rect.addTo(graph);
var rectView = rect.findView(paper);
assert.ok(onViewPostponedSpy.calledOnce);
assert.ok(onViewPostponedSpy.calledWithExactly(rectView, sinon.match.number, paper));
assert.ok(onViewPostponedSpy.calledOn(paper));
onViewPostponedSpy.resetHistory();
rect.translate(10, 0);
assert.ok(onViewPostponedSpy.notCalled);
});
QUnit.test('force postponed view update', function(assert) {
paper.options.viewport = function(view) { return view.model.isLink(); };
var onViewPostponedSpy = sinon.spy(paper.options, 'onViewPostponed');
var rect1 = new joint.shapes.standard.Rectangle();
var rect2 = new joint.shapes.standard.Rectangle();
var link = new joint.shapes.standard.Link();
link.source(rect1);
link.target(rect2);
paper.freeze();
link.addTo(graph);
rect1.addTo(graph);
rect2.addTo(graph);
paper.unfreeze();
assert.ok(onViewPostponedSpy.calledOnce);
assert.ok(onViewPostponedSpy.calledWithExactly(link.findView(paper), sinon.match.number, paper));
assert.equal(cellNodesCount(paper), 3);
assert.equal(3, paper.getMountedViews().length);
assert.equal(0, paper.getUnmountedViews().length);
});
});
});
QUnit.module('prototype', function() {
QUnit.module('updateViews()', function() {
QUnit.module('options', function() {
QUnit.test('batchSize', function(assert) {
paper.freeze();
var rect1 = new joint.shapes.standard.Rectangle();
var rect2 = new joint.shapes.standard.Rectangle();
rect1.addTo(graph);
rect2.addTo(graph);
var res = paper.updateViews({ batchSize: 1 });
assert.deepEqual(res, { batches: 2, updated: 2, priority: 0 });
assert.equal(cellNodesCount(paper), 2);
});
QUnit.module('viewport', function() {
QUnit.test('sanity', function(assert) {
paper.freeze();
var rect1 = new joint.shapes.standard.Rectangle();
var rect2 = new joint.shapes.standard.Rectangle();
rect1.addTo(graph);
rect2.addTo(graph);
var viewportSpy = sinon.spy(function() { return true; });
var res = paper.updateViews({ viewport: viewportSpy });
assert.deepEqual(res, { batches: 1, updated: 2, priority: 0 });
assert.equal(cellNodesCount(paper), 2);
assert.ok(viewportSpy.calledTwice);
assert.equal(2, paper.getMountedViews().length);
assert.equal(0, paper.getUnmountedViews().length);
// Unmount a view because it's not in the viewport and update views with a different viewport
paper.checkViewport({ viewport: function() { return false; } });
rect1.translate(10, 0);
assert.equal(0, paper.getMountedViews().length);
assert.equal(2, paper.getUnmountedViews().length);
paper.updateViews({ viewport: function() { return true; } });
assert.equal(cellNodesCount(paper), 1);
assert.equal(1, paper.getMountedViews().length);
assert.equal(1, paper.getUnmountedViews().length);
});
QUnit.test('view removal', function(assert) {
var rect1 = new joint.shapes.standard.Rectangle();
rect1.addTo(graph);
assert.ok(paper.findViewByModel(rect1));
paper.freeze();
rect1.remove();
paper.updateViews({ viewport: function() { return false; } });
assert.notOk(paper.findViewByModel(rect1));
});
QUnit.test('detachable', function(assert) {
paper.options.elementView = joint.dia.ElementView.extend({
DETACHABLE: false
});
var rect1 = new joint.shapes.standard.Rectangle();
rect1.addTo(graph);
paper.freeze();
paper.checkViewport({ viewport: function() { return false; } });
assert.equal(cellNodesCount(paper), 1);
});
});
});
});
QUnit.test('dumpViews()', function(assert) {
var rect1 = new joint.shapes.standard.Rectangle();
var rect2 = new joint.shapes.standard.Rectangle();
var link = new joint.shapes.standard.Link();
rect1.resize(100, 100);
rect2.resize(100, 100);
rect2.position(200, 0);
link.source(rect1);
link.target(rect2);
paper.options.viewport = function(view) { return view.model === rect1; };
rect1.addTo(graph);
rect2.addTo(graph);
link.addTo(graph);
assert.equal(cellNodesCount(paper), 1);
paper.dumpViews();
assert.equal(cellNodesCount(paper), 3);
assert.checkBbox(paper, rect1, 0, 0, 100, 100);
assert.checkBbox(paper, rect2, 200, 0, 100, 100);
assert.checkBbox(paper, link, 100, 50, 100, 0);
});
QUnit.test('checkViewport()', function(assert) {
var rect1 = new joint.shapes.standard.Rectangle();
var rect2 = new joint.shapes.standard.Rectangle();
var rect3 = new joint.shapes.standard.Rectangle();
var rectNever = new joint.shapes.standard.Rectangle();
var rectAlways = new joint.shapes.standard.Rectangle();
paper.options.viewport = function(view) { return [rect1, rectAlways].indexOf(view.model) > -1; };
paper.freeze();
rect1.addTo(graph);
rect2.addTo(graph);
rect3.addTo(graph);
rectNever.addTo(graph);
rectAlways.addTo(graph);
paper.unfreeze();
var rect1View = rect1.findView(paper);
var rect2View = rect2.findView(paper);
var rect3View = rect3.findView(paper);
var rectAlwaysView = rectAlways.findView(paper);
paper.options.viewport = function(view) { return [rect2, rect3, rectAlways].indexOf(view.model) > -1; };
assert.equal(cellNodesCount(paper), 2);
assert.equal(rect1View.el.parentNode, paper.cells);
assert.equal(rectAlwaysView.el.parentNode, paper.cells);
var res1 = paper.checkViewport();
assert.deepEqual(res1, { mounted: 2, unmounted: 1 });
paper.updateViews();
assert.equal(cellNodesCount(paper), 3);
assert.equal(rect2View.el.parentNode, paper.cells);
assert.equal(rect3View.el.parentNode, paper.cells);
assert.equal(rectAlwaysView.el.parentNode, paper.cells);
paper.options.viewport = function(view) { return [rect1, rectAlways].indexOf(view.model) > -1; };
var res2 = paper.checkViewport();
assert.deepEqual(res2, { mounted: 1, unmounted: 2 });
paper.updateViews();
assert.equal(cellNodesCount(paper), 2);
assert.equal(rect1.findView(paper).el.parentNode, paper.cells);
assert.equal(rectAlwaysView.el.parentNode, paper.cells);
});
QUnit.test('requireView()', function(assert) {
assert.equal(paper.requireView(), null);
paper.options.viewport = function() { return false; };
var rect = new joint.shapes.standard.Rectangle();
rect.translate(201, 202);
rect.resize(101, 102);
rect.addTo(graph);
var rectView = rect.findView(paper);
assert.notOk(rectView.el.parentNode);
rectView = paper.requireView(rect);
assert.ok(rectView.el.parentNode, paper.cells);
assert.checkBbox(paper, rect, 201, 202, 101, 102);
});
QUnit.module('freeze(), unfreeze(), isFrozen()', function() {
QUnit.test('sanity', function(assert) {
assert.equal(cellNodesCount(paper), 0);
assert.notOk(paper.isFrozen());
paper.freeze();
assert.ok(paper.isFrozen());
var rect = new joint.shapes.standard.Rectangle();
rect.addTo(graph);
assert.ok(paper.isFrozen());
assert.equal(cellNodesCount(paper), 0);
assert.equal(0, paper.getMountedViews().length);
assert.equal(1, paper.getUnmountedViews().length);
paper.unfreeze();
assert.notOk(paper.isFrozen());
assert.equal(cellNodesCount(paper), 1);
assert.equal(1, paper.getMountedViews().length);
assert.equal(0, paper.getUnmountedViews().length);
});
QUnit.test('add+remove+change+add while fro