import type {Layout} from 'react-grid-layout'; import { calculateColumnDepths, getNextAvailablePosition, } from 'sentry/views/dashboards/layoutUtils'; describe('Dashboards > Utils', () => { describe('calculateColumnDepths', () => { it('returns 0s when layouts is empty', () => { const layout = []; const expectedColumnDepths = [0, 0, 0, 0, 0, 0]; const columnDepths = calculateColumnDepths(layout); expect(columnDepths).toEqual(expectedColumnDepths); }); it('returns the depth of layouts at the same level', () => { const layout = [ {x: 0, y: 0, w: 1, h: 3}, {x: 1, y: 0, w: 2, h: 2}, {x: 4, y: 0, w: 2, h: 4}, ] as Layout[]; const expectedColumnDepths = [3, 2, 2, 0, 4, 4]; const columnDepths = calculateColumnDepths(layout); expect(columnDepths).toEqual(expectedColumnDepths); }); it('ignores any "space" above and returns the depth of a lower widget', () => { const layout = [{x: 0, y: 6, w: 2, h: 3}] as Layout[]; const expectedColumnDepths = [9, 9, 0, 0, 0, 0]; const columnDepths = calculateColumnDepths(layout); expect(columnDepths).toEqual(expectedColumnDepths); }); }); describe('getNextAvailablePosition', () => { it('returns 0, 0 when there is space for a widget in the top left', () => { const columnDepths = [0, 0, 1, 1, 0, 0]; const expectedPosition = {x: 0, y: 0}; const expectedNextColumnDepths = [2, 2, 1, 1, 0, 0]; const [position, nextColumnDepths] = getNextAvailablePosition(columnDepths, 2); expect(position).toEqual(expectedPosition); expect(nextColumnDepths).toEqual(expectedNextColumnDepths); }); it('returns the middle position if there is space', () => { const columnDepths = [1, 1, 0, 0, 1, 1]; const expectedPosition = {x: 2, y: 0}; const expectedNextColumnDepths = [1, 1, 2, 2, 1, 1]; const [position, nextColumnDepths] = getNextAvailablePosition(columnDepths, 2); expect(position).toEqual(expectedPosition); expect(nextColumnDepths).toEqual(expectedNextColumnDepths); }); it('returns top right if there is space', () => { const columnDepths = [1, 1, 1, 1, 0, 0]; const expectedPosition = {x: 4, y: 0}; const expectedNextColumnDepths = [1, 1, 1, 1, 2, 2]; const [position, nextColumnDepths] = getNextAvailablePosition(columnDepths, 2); expect(position).toEqual(expectedPosition); expect(nextColumnDepths).toEqual(expectedNextColumnDepths); }); it('returns next row if there is no space', () => { const columnDepths = [1, 1, 1, 1, 1, 1]; const expectedPosition = {x: 0, y: 1}; const expectedNextColumnDepths = [3, 3, 1, 1, 1, 1]; const [position, nextColumnDepths] = getNextAvailablePosition(columnDepths, 2); expect(position).toEqual(expectedPosition); expect(nextColumnDepths).toEqual(expectedNextColumnDepths); }); it('returns the next column depth for multiple sequential calculations', () => { const initialColumnDepths = [1, 1, 1, 1, 0, 0]; const expectedPosition = {x: 0, y: 1}; const expectedNextColumnDepths = [3, 3, 1, 1, 2, 2]; // Call it twice and pass the output of the first into the second const [_, intermediateDepths] = getNextAvailablePosition(initialColumnDepths, 2); const [position, finalColumnDepths] = getNextAvailablePosition( intermediateDepths, 2 ); expect(position).toEqual(expectedPosition); expect(finalColumnDepths).toEqual(expectedNextColumnDepths); }); it('returns proper next column depth with different height', () => { const columnDepths = [1, 1, 1, 1, 1, 1]; const expectedPosition = {x: 0, y: 1}; const expectedNextColumnDepths = [5, 5, 1, 1, 1, 1]; const [position, nextColumnDepths] = getNextAvailablePosition(columnDepths, 4); expect(position).toEqual(expectedPosition); expect(nextColumnDepths).toEqual(expectedNextColumnDepths); }); it('does not mutate its input array', () => { const columnDepths = [1, 1, 1, 1, 1, 1]; getNextAvailablePosition(columnDepths, 4); expect(columnDepths).toEqual([1, 1, 1, 1, 1, 1]); }); }); });