/* jshint -W117 */ const placing = require('../src/placing'); describe('getBounds', () => { test('no nodes', () => { const res = placing().getBounds({}); expect(res).toEqual({x: 0, y: 0, w: 0, h: 0}); }); test('no placed nodes', () => { const res = placing().getBounds({ 'a': {}, 'b': {} }); expect(res).toEqual({x: 0, y: 0, w: 0, h: 0}); }); test('first node', () => { const res = placing().getBounds({ 'a': {x: 0, y: 0}, 'b': {} }); expect(res).toEqual({x: 0, y: 0, w: 1, h: 1}); }); test('one node not 0,0', () => { const res = placing().getBounds({ 'a': {x: 5, y: 6}, 'b': {} }); expect(res).toEqual({x: 5, y: 6, w: 1, h: 1}); }); test('2 nodes', () => { const res = placing().getBounds({ 'a': {x: 0, y: 0}, 'b': {x: 1, y: 1}, 'c': {} }); expect(res).toEqual({x: 0, y: 0, w: 2, h: 2}); }); test('2 nodes special', () => { const res = placing().getBounds({ 'a': {x: 1, y: 2}, 'b': {x: -5, y: 6}, 'c': {} }); expect(res).toEqual({x: -5, y: 2, w: 7, h: 5}); }); }); describe('getNewPos', () => { test('no nodes', () => { const res = placing().getNewPos({}); expect(res).toEqual({x: 0, y: 0}); }); test('no placed nodes', () => { const res = placing().getNewPos({ 'a': {}, 'b': {} }); expect(res).toEqual({x: 0, y: 0}); }); test('one node', () => { const res = placing().getNewPos({ 'a': {x: 0, y: 0}, 'b': {} }); expect(res).toEqual({x: 1, y: 0}); }); test('one node not 0,0', () => { const res = placing().getNewPos({ 'a': {x: 5, y: 6}, 'b': {} }); expect(res).toEqual({x: 6, y: 6}); }); test('2 nodes', () => { const res = placing().getNewPos({ 'a': {x: 0, y: 0}, 'b': {x: 1, y: 1} }); expect(res).toEqual({x: 1, y: 0}); }); }); describe('nodeBetween', () => { test('only 2 nodes', () => { const res = placing().nodeBetween({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 1, y: 0} }, 'a', 'b'); expect(res).toBe(false); }); test('other node not between', () => { const res = placing().nodeBetween({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 0, y: 1}, 'c': {name: 'c', x: 1, y: 0} }, 'a', 'b'); expect(res).toBe(false); }); test('between aligned h', () => { const res = placing().nodeBetween({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 0}, 'c': {name: 'c', x: 1, y: 0} }, 'a', 'b'); expect(res).toBe(true); }); test('between aligned v', () => { const res = placing().nodeBetween({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 0, y: 2}, 'c': {name: 'c', x: 0, y: 1} }, 'a', 'b'); expect(res).toBe(true); }); test('between diagonal', () => { const res = placing().nodeBetween({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 2}, 'c': {name: 'c', x: 1, y: 1} }, 'a', 'b'); expect(res).toBe(true); }); test('between diagonal 2', () => { const res = placing().nodeBetween({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 1}, 'c': {name: 'c', x: 1, y: 1} }, 'a', 'b'); expect(res).toBe(true); }); test('between diagonal 3', () => { const res = placing().nodeBetween({ '1': {'name': '1', 'x': 1, 'y': 0}, '2': {'name': '2', 'x': 2, 'y': 0}, '3': {'name': '3', 'x': 1, 'y': 1}, '4': {'name': '4', 'x': 2, 'y': 1}, '5': {'name': '5', 'x': 0, 'y': 0}, '6': {'name': '6', 'x': 0, 'y': 1} }, '4', '5'); expect(res).toBe(true); }); }); describe('getPosition', () => { test('free node', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: [], afterY: [], beforeY: [] } }, 'b': {x: 0, y: 0} }, 'a', true); expect(res).toEqual({x: null, y: null, free: true}); }); test('constrained to another not placed', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: ['b'], afterY: [], beforeY: [] } }, 'b': {} }, 'a', true); expect(res).toEqual({x: null, y: null, free: true}); }); test('constrained to another left', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: ['b'], afterY: [], beforeY: [] } }, 'b': {x: 0, y: 0} }, 'a', true); expect(res).toEqual({x: 1, y: 0, free: false}); }); test('constrained to another right', () => { const res = placing().getPosition({ 'a': { const: { afterX: ['b'], beforeX: [], afterY: [], beforeY: [] } }, 'b': {x: 0, y: 0} }, 'a', true); expect(res).toEqual({x: -1, y: 0, free: false}); }); test('constrained to another up', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: [], afterY: [], beforeY: ['b'] } }, 'b': {x: 0, y: 0} }, 'a', true); expect(res).toEqual({x: 0, y: 1, free: false}); }); test('constrained to another down', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: [], afterY: ['b'], beforeY: [] } }, 'b': {x: 0, y: 0} }, 'a', true); expect(res).toEqual({x: 0, y: -1, free: false}); }); test('double constrained diagonal', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: ['b'], afterY: ['c'], beforeY: [] } }, 'b': {x: 0, y: 0}, 'c': {x: 2, y: 1} }, 'a', true); expect(res).toEqual({x: 1, y: 0, free: false}); }); test('double constrained no diagonal', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: ['b'], afterY: ['c'], beforeY: [] } }, 'b': {x: 0, y: 0}, 'c': {x: 2, y: 1} }, 'a', false); expect(res).toEqual({x: 2, y: 0, free: false}); }); test('double constrained impossible', () => { const res = placing().getPosition({ 'a': { const: { afterX: [], beforeX: ['b'], afterY: ['c'], beforeY: [] } }, 'b': {x: 0, y: 0}, 'c': {x: 2, y: 10} }, 'a', false); expect(res).toEqual(null); }); }); describe('isValid', () => { test('no nodes', () => { const res = placing().isValid({}, []); expect(res).toBe(true); }); test('no placed nodes', () => { const res = placing().isValid({ 'a': {}, 'b': {} }, [ {from: 'a', to: 'b'} ]); expect(res).toBe(true); }); test('one nodes', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {} }, [ {from: 'a', to: 'b'} ]); expect(res).toBe(true); }); test('overlapping nodes', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 0, y: 0} }, []); expect(res).toBe(false); }); test('in between node', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 0}, 'c': {name: 'c', x: 1, y: 0} }, [ {from: 'a', to: 'b'} ]); expect(res).toBe(false); }); test('too far node', () => { const res = placing({diagonals: true, 'max-link-length': 4}).isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 4, y: 2} }, [ {from: 'a', to: 'b'} ]); expect(res).toBe(false); }); test('invalid right link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: -2, y: 2} }, [ {from: 'a', to: 'b', direction: 'right'} ]); expect(res).toBe(false); }); test('invalid left link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 2} }, [ {from: 'a', to: 'b', direction: 'left'} ]); expect(res).toBe(false); }); test('invalid up link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 2} }, [ {from: 'a', to: 'b', direction: 'up'} ]); expect(res).toBe(false); }); test('invalid down link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: -2} }, [ {from: 'a', to: 'b', direction: 'down'} ]); expect(res).toBe(false); }); test('valid right link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 2} }, [ {from: 'a', to: 'b', direction: 'right'} ]); expect(res).toBe(true); }); test('valid left link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: -2, y: 2} }, [ {from: 'a', to: 'b', direction: 'left'} ]); expect(res).toBe(true); }); test('valid up link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: -2} }, [ {from: 'a', to: 'b', direction: 'up'} ]); expect(res).toBe(true); }); test('valid down link', () => { const res = placing().isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 2} }, [ {from: 'a', to: 'b', direction: 'down'} ]); expect(res).toBe(true); }); test('invalid diagonal link', () => { const res = placing({diagonals: false}).isValid({ 'a': {name: 'a', x: 0, y: 0}, 'b': {name: 'b', x: 2, y: 2} }, [ {from: 'a', to: 'b'} ]); expect(res).toBe(false); }); }); describe('correctPlacing', () => { test('no nodes', () => { const nodes = {}; placing().correctPlacing(nodes); expect(nodes).toEqual({}); }); test('several nodes', () => { const nodes = { 'a': {x: 3, y: 2}, 'b': {x: -2, y: 5}, 'c': {x: -4, y: 3} }; placing().correctPlacing(nodes); expect(nodes).toEqual({ 'a': {x: 7, y: 0}, 'b': {x: 2, y: 3}, 'c': {x: 0, y: 1} }); }); }); describe('compute', () => { const createNodes = (n) => { const nodes = {}; new Array(n).fill(0).forEach((u, i) => nodes['' + (i + 1)] = {name: '' + (i + 1)}); return nodes; }; test('no nodes', () => { const nodes = placing().compute({}, []); expect(nodes).toEqual({}); }); test('invalid node', () => { try { placing().compute({ 'a': {name: 'a'}, 'b': {name: 'b', x: 'hello'} }, []); fail('no error thrown'); } catch (err) { expect(err).toBe('Node \'b\' is invalid at key \'x\''); } }); test('invalid link', () => { try { placing().compute({}, [{from: 'a', to: 'b'}, {from: 'a', to: 5}]); fail('no error thrown'); } catch (err) { expect(err).toBe('Link 1 (a->5) is invalid at key \'to\''); } }); test('3 nodes no link', () => { const nodes = placing({diagonals: false}).compute(createNodes(3), []); expect(nodes).toEqual({ '1': {name: '1', x: 0, y: 0}, '2': {name: '2', x: 1, y: 0}, '3': {name: '3', x: 0, y: 1} }); }); test('6 nodes 6 links with directions', () => { const nodes = placing().compute(createNodes(6), [ {from: '1', to: '2', direction: 'right'}, {from: '1', to: '3', direction: 'down'}, {from: '3', to: '4', direction: 'right'}, {from: '4', to: '5', direction: 'up'}, {from: '3', to: '6', direction: 'left'} ]); expect(nodes).toEqual({ '1': {name: '1', x: 0, y: 0}, '2': {name: '2', x: 1, y: 0}, '3': {name: '3', x: 1, y: 1}, '4': {name: '4', x: 2, y: 1}, '5': {name: '5', x: 2, y: 0}, '6': {name: '6', x: 0, y: 1} }); }); test('6 nodes 6 links with directions no diagonals', () => { const nodes = placing({diagonals: false}).compute(createNodes(6), [ {from: '1', to: '2', direction: 'right'}, {from: '1', to: '3', direction: 'down'}, {from: '3', to: '4', direction: 'right'}, {from: '4', to: '5', direction: 'up'}, {from: '3', to: '6', direction: 'left'} ]); expect(nodes).toEqual({ '1': {name: '1', x: 1, y: 0}, '2': {name: '2', x: 2, y: 0}, '3': {name: '3', x: 1, y: 1}, '4': {name: '4', x: 3, y: 1}, '5': {name: '5', x: 3, y: 0}, '6': {name: '6', x: 0, y: 1} }); }); test('6 nodes 6 links no directions', () => { const nodes = placing().compute(createNodes(6), [ {from: '1', to: '2'}, {from: '1', to: '3'}, {from: '3', to: '4'}, {from: '4', to: '5'}, {from: '3', to: '6'} ]); expect(nodes).toEqual({ '1': {name: '1', x: 0, y: 0}, '2': {name: '2', x: 1, y: 0}, '3': {name: '3', x: 1, y: 1}, '4': {name: '4', x: 2, y: 0}, '5': {name: '5', x: 2, y: 1}, '6': {name: '6', x: 0, y: 1} }); }); test('6 nodes 6 links no directions no diagonals', () => { const nodes = placing({diagonals: false}).compute(createNodes(6), [ {from: '1', to: '2'}, {from: '1', to: '3'}, {from: '3', to: '4'}, {from: '4', to: '5'}, {from: '3', to: '6'} ]); expect(nodes).toEqual({ '1': {name: '1', x: 0, y: 0}, '2': {name: '2', x: 0, y: 1}, '3': {name: '3', x: 1, y: 0}, '4': {name: '4', x: 1, y: 1}, '5': {name: '5', x: 2, y: 1}, '6': {name: '6', x: 2, y: 0} }); }); test('3 nodes impossible', () => { const nodes = placing({diagonals: false}).compute(createNodes(3), [ {from: '1', to: '2', direction: 'left'}, {from: '1', to: '3', direction: 'left'}, ]); expect(nodes).toBeNull(); }); });