UNPKG

gridstack

Version:

TypeScript/JS lib for dashboard layout and creation, responsive, mobile support, no external dependencies, with many wrappers (React, Angular, Vue, Ember, knockout...)

358 lines 16.9 kB
import { GridStackEngine } from '../src/gridstack-engine'; describe('gridstack engine:', () => { 'use strict'; let e; let ePriv; // cast engine for private vars access let findNode = function (id) { return e.nodes.find(n => n.id === id); }; it('should exist setup function.', () => { expect(GridStackEngine).not.toBeNull(); expect(typeof GridStackEngine).toBe('function'); }); describe('test constructor >', () => { it('should be setup properly', () => { ePriv = e = new GridStackEngine(); expect(e.column).toEqual(12); expect(e.float).toEqual(false); expect(e.maxRow).toEqual(undefined); expect(e.nodes).toEqual([]); expect(e.batchMode).toEqual(undefined); expect(ePriv.onChange).toEqual(undefined); }); it('should set params correctly.', () => { let fkt = () => { }; let arr = [1, 2, 3]; ePriv = e = new GridStackEngine({ column: 1, onChange: fkt, float: true, maxRow: 2, nodes: arr }); expect(e.column).toEqual(1); expect(e.float).toBe(true); expect(e.maxRow).toEqual(2); expect(e.nodes).toEqual(arr); expect(e.batchMode).toEqual(undefined); expect(ePriv.onChange).toEqual(fkt); }); }); describe('batch update', () => { it('should set float and batchMode when calling batchUpdate.', () => { ePriv = e = new GridStackEngine({ float: true }); e.batchUpdate(); expect(e.float).toBe(true); expect(e.batchMode).toBe(true); }); }); describe('test prepareNode >', () => { beforeAll(() => { ePriv = e = new GridStackEngine(); }); it('should prepare a node', () => { expect(e.prepareNode({}, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(e.prepareNode({ x: 10 }, false)).toEqual(expect.objectContaining({ x: 10, y: 0, h: 1 })); expect(e.prepareNode({ x: -10 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(e.prepareNode({ y: 10 }, false)).toEqual(expect.objectContaining({ x: 0, y: 10, h: 1 })); expect(e.prepareNode({ y: -10 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(e.prepareNode({ w: 3 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, w: 3, h: 1 })); expect(e.prepareNode({ w: 100 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, w: 12, h: 1 })); expect(e.prepareNode({ w: 0 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(e.prepareNode({ w: -190 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(e.prepareNode({ h: 3 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 3 })); expect(e.prepareNode({ h: 0 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(e.prepareNode({ h: -10 }, false)).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(e.prepareNode({ x: 4, w: 10 }, false)).toEqual(expect.objectContaining({ x: 2, y: 0, w: 10, h: 1 })); expect(e.prepareNode({ x: 4, w: 10 }, true)).toEqual(expect.objectContaining({ x: 4, y: 0, w: 8, h: 1 })); }); }); describe('sorting of nodes >', () => { beforeAll(() => { ePriv = e = new GridStackEngine(); e.nodes = [{ x: 7, y: 0 }, { x: 4, y: 4 }, { x: 9, y: 0 }, { x: 0, y: 1 }]; }); it('should sort ascending with 12 columns.', () => { e.sortNodes(1); expect(e.nodes).toEqual([{ x: 7, y: 0 }, { x: 9, y: 0 }, { x: 0, y: 1 }, { x: 4, y: 4 }]); }); it('should sort descending with 12 columns.', () => { e.sortNodes(-1); expect(e.nodes).toEqual([{ x: 4, y: 4 }, { x: 0, y: 1 }, { x: 9, y: 0 }, { x: 7, y: 0 }]); }); it('should sort ascending without columns.', () => { ePriv.column = undefined; e.sortNodes(1); expect(e.nodes).toEqual([{ x: 7, y: 0 }, { x: 9, y: 0 }, { x: 0, y: 1 }, { x: 4, y: 4 }]); }); it('should sort descending without columns.', () => { ePriv.column = undefined; e.sortNodes(-1); expect(e.nodes).toEqual([{ x: 4, y: 4 }, { x: 0, y: 1 }, { x: 9, y: 0 }, { x: 7, y: 0 }]); }); }); describe('test isAreaEmpty >', () => { beforeAll(() => { ePriv = e = new GridStackEngine({ float: true }); e.nodes = [ e.prepareNode({ x: 3, y: 2, w: 3, h: 2 }) ]; }); it('should be true', () => { expect(e.isAreaEmpty(0, 0, 3, 2)).toEqual(true); expect(e.isAreaEmpty(3, 4, 3, 2)).toEqual(true); }); it('should be false', () => { expect(e.isAreaEmpty(1, 1, 3, 2)).toEqual(false); expect(e.isAreaEmpty(2, 3, 3, 2)).toEqual(false); }); }); describe('test cleanNodes/getDirtyNodes >', () => { beforeAll(() => { ePriv = e = new GridStackEngine({ float: true }); e.nodes = [ e.prepareNode({ x: 0, y: 0, id: '1', _dirty: true }), e.prepareNode({ x: 3, y: 2, w: 3, h: 2, id: '2', _dirty: true }), e.prepareNode({ x: 3, y: 7, w: 3, h: 2, id: '3' }) ]; }); beforeEach(() => { delete ePriv.batchMode; }); it('should return all dirty nodes', () => { let nodes = e.getDirtyNodes(); expect(nodes.length).toEqual(2); expect(nodes[0].id).toEqual('1'); expect(nodes[1].id).toEqual('2'); }); it('should\'n clean nodes if batchMode true', () => { e.batchMode = true; e.cleanNodes(); expect(e.getDirtyNodes().length).toBeGreaterThan(0); }); it('should clean all dirty nodes', () => { e.cleanNodes(); expect(e.getDirtyNodes().length).toEqual(0); }); }); describe('test batchUpdate/commit >', () => { beforeAll(() => { ePriv = e = new GridStackEngine(); }); it('should work on not float grids', () => { expect(e.float).toEqual(false); e.batchUpdate(); e.batchUpdate(); // double for code coverage expect(e.batchMode).toBe(true); expect(e.float).toEqual(true); e.batchUpdate(false); e.batchUpdate(false); expect(e.batchMode).not.toBe(true); expect(e.float).not.toBe(true); }); it('should work on float grids', () => { e.float = true; e.batchUpdate(); expect(e.batchMode).toBe(true); expect(e.float).toEqual(true); e.batchUpdate(false); expect(e.batchMode).not.toBe(true); expect(e.float).toEqual(true); }); }); describe('test batchUpdate/commit >', () => { beforeAll(() => { ePriv = e = new GridStackEngine({ float: true }); }); it('should work on float grids', () => { expect(e.float).toEqual(true); e.batchUpdate(); expect(e.batchMode).toBe(true); expect(e.float).toEqual(true); e.batchUpdate(false); expect(e.batchMode).not.toBe(true); expect(e.float).toEqual(true); }); }); describe('test _notify >', () => { let spy; beforeEach(() => { spy = { callback: () => { } }; vi.spyOn(spy, 'callback'); ePriv = e = new GridStackEngine({ float: true, onChange: spy.callback }); e.nodes = [ e.prepareNode({ x: 0, y: 0, id: '1', _dirty: true }), e.prepareNode({ x: 3, y: 2, w: 3, h: 2, id: '2', _dirty: true }), e.prepareNode({ x: 3, y: 7, w: 3, h: 2, id: '3' }) ]; }); it('should\'n be called if batchMode true', () => { e.batchMode = true; ePriv._notify(); expect(spy.callback).not.toHaveBeenCalled(); }); it('should by called with dirty nodes', () => { ePriv._notify(); expect(spy.callback).toHaveBeenCalledWith([e.nodes[0], e.nodes[1]]); }); it('should by called with extra passed node to be removed', () => { let n1 = { id: -1 }; ePriv._notify([n1]); expect(spy.callback).toHaveBeenCalledWith([n1, e.nodes[0], e.nodes[1]]); }); }); describe('test _packNodes >', () => { describe('using float:false mode >', () => { beforeEach(() => { ePriv = e = new GridStackEngine({ float: false }); }); it('shouldn\'t pack one node with y coord eq 0', () => { e.nodes = [ e.prepareNode({ x: 0, y: 0, w: 1, h: 1, id: '1' }), ]; ePriv._packNodes(); expect(findNode('1')).toEqual(expect.objectContaining({ x: 0, y: 0, h: 1 })); expect(findNode('1')._dirty).toBeFalsy(); }); it('should pack one node correctly', () => { e.nodes = [ e.prepareNode({ x: 0, y: 1, w: 1, h: 1, id: '1' }), ]; ePriv._packNodes(); expect(findNode('1')).toEqual(expect.objectContaining({ x: 0, y: 0, _dirty: true })); }); it('should pack nodes correctly', () => { e.nodes = [ e.prepareNode({ x: 0, y: 1, w: 1, h: 1, id: '1' }), e.prepareNode({ x: 0, y: 5, w: 1, h: 1, id: '2' }), ]; ePriv._packNodes(); expect(findNode('1')).toEqual(expect.objectContaining({ x: 0, y: 0, _dirty: true })); expect(findNode('2')).toEqual(expect.objectContaining({ x: 0, y: 1, _dirty: true })); }); it('should pack reverse nodes correctly', () => { e.nodes = [ e.prepareNode({ x: 0, y: 5, w: 1, h: 1, id: '1' }), e.prepareNode({ x: 0, y: 1, w: 1, h: 1, id: '2' }), ]; ePriv._packNodes(); expect(findNode('2')).toEqual(expect.objectContaining({ x: 0, y: 0, _dirty: true })); expect(findNode('1')).toEqual(expect.objectContaining({ x: 0, y: 1, _dirty: true })); }); it('should respect locked nodes', () => { e.nodes = [ e.prepareNode({ x: 0, y: 1, w: 1, h: 1, id: '1', locked: true }), e.prepareNode({ x: 0, y: 5, w: 1, h: 1, id: '2' }), ]; ePriv._packNodes(); expect(findNode('1')).toEqual(expect.objectContaining({ x: 0, y: 1, h: 1 })); expect(findNode('1')._dirty).toBeFalsy(); expect(findNode('2')).toEqual(expect.objectContaining({ x: 0, y: 2, _dirty: true })); }); }); }); describe('test changedPos >', () => { beforeAll(() => { ePriv = e = new GridStackEngine(); }); it('should return true for changed x', () => { let widget = { x: 1, y: 2, w: 3, h: 4 }; expect(e.changedPosConstrain(widget, { x: 2, y: 2 })).toEqual(true); }); it('should return true for changed y', () => { let widget = { x: 1, y: 2, w: 3, h: 4 }; expect(e.changedPosConstrain(widget, { x: 1, y: 1 })).toEqual(true); }); it('should return true for changed width', () => { let widget = { x: 1, y: 2, w: 3, h: 4 }; expect(e.changedPosConstrain(widget, { x: 2, y: 2, w: 4, h: 4 })).toEqual(true); }); it('should return true for changed height', () => { let widget = { x: 1, y: 2, w: 3, h: 4 }; expect(e.changedPosConstrain(widget, { x: 1, y: 2, w: 3, h: 3 })).toEqual(true); }); it('should return false for unchanged position', () => { let widget = { x: 1, y: 2, w: 3, h: 4 }; expect(e.changedPosConstrain(widget, { x: 1, y: 2, w: 3, h: 4 })).toEqual(false); }); }); describe('test locked widget >', () => { beforeAll(() => { ePriv = e = new GridStackEngine(); }); it('should add widgets around locked one', () => { let nodes = [ { x: 0, y: 1, w: 12, h: 1, locked: true, noMove: true, noResize: true, id: '0' }, { x: 1, y: 0, w: 2, h: 3, id: '1' } ]; // add locked item e.addNode(nodes[0]); expect(findNode('0')).toEqual(expect.objectContaining({ x: 0, y: 1, w: 12, h: 1, locked: true })); // add item that moves past locked one e.addNode(nodes[1]); expect(findNode('0')).toEqual(expect.objectContaining({ x: 0, y: 1, w: 12, h: 1, locked: true })); expect(findNode('1')).toEqual(expect.objectContaining({ x: 1, y: 2, h: 3 })); // locked item can still be moved directly (what user does) let node0 = findNode('0'); expect(e.moveNode(node0, { y: 6 })).toEqual(true); expect(findNode('0')).toEqual(expect.objectContaining({ x: 0, y: 6, h: 1, locked: true })); // but moves regular one past it let node1 = findNode('1'); expect(e.moveNode(node1, { x: 6, y: 6 })).toEqual(true); expect(node1).toEqual(expect.objectContaining({ x: 6, y: 7, w: 2, h: 3 })); // but moves regular one before (gravity ON) e.float = false; expect(e.moveNode(node1, { x: 7, y: 3 })).toEqual(true); expect(node1).toEqual(expect.objectContaining({ x: 7, y: 0, w: 2, h: 3 })); // but moves regular one before (gravity OFF) e.float = true; expect(e.moveNode(node1, { x: 7, y: 3 })).toEqual(true); expect(node1).toEqual(expect.objectContaining({ x: 7, y: 3, w: 2, h: 3 })); }); }); describe('test columnChanged >', () => { beforeAll(() => { }); it('12 to 1 and back', () => { ePriv = e = new GridStackEngine({ column: 12 }); // Add two side-by-side components 6+6 = 12 columns const left = e.addNode({ x: 0, y: 0, w: 6, h: 1, id: 'left' }); const right = e.addNode({ x: 6, y: 0, w: 6, h: 1, id: 'right' }); expect(left).toEqual(expect.objectContaining({ x: 0, y: 0, w: 6, h: 1 })); expect(right).toEqual(expect.objectContaining({ x: 6, y: 0, w: 6, h: 1 })); // Resize to 1 column e.column = 1; e.columnChanged(12, 1); expect(left).toEqual(expect.objectContaining({ x: 0, y: 0, w: 1, h: 1 })); expect(right).toEqual(expect.objectContaining({ x: 0, y: 1, w: 1, h: 1 })); // Resize back to 12 column e.column = 12; e.columnChanged(1, 12); expect(left).toEqual(expect.objectContaining({ x: 0, y: 0, w: 6, h: 1 })); expect(right).toEqual(expect.objectContaining({ x: 6, y: 0, w: 6, h: 1 })); }); it('24 column to 1 and back', () => { ePriv = e = new GridStackEngine({ column: 24 }); // Add two side-by-side components 12+12 = 24 columns const left = e.addNode({ x: 0, y: 0, w: 12, h: 1, id: 'left' }); const right = e.addNode({ x: 12, y: 0, w: 12, h: 1, id: 'right' }); expect(left).toEqual(expect.objectContaining({ x: 0, y: 0, w: 12, h: 1 })); expect(right).toEqual(expect.objectContaining({ x: 12, y: 0, w: 12, h: 1 })); // Resize to 1 column e.column = 1; e.columnChanged(24, 1); expect(left).toEqual(expect.objectContaining({ x: 0, y: 0, w: 1, h: 1 })); expect(right).toEqual(expect.objectContaining({ x: 0, y: 1, w: 1, h: 1 })); // Resize back to 24 column e.column = 24; e.columnChanged(1, 24); expect(left).toEqual(expect.objectContaining({ x: 0, y: 0, w: 12, h: 1 })); expect(right).toEqual(expect.objectContaining({ x: 12, y: 0, w: 12, h: 1 })); }); }); describe('test compact >', () => { beforeAll(() => { ePriv = e = new GridStackEngine(); }); it('do nothing', () => { e.compact(); }); }); }); //# sourceMappingURL=gridstack-engine-spec.js.map