import type { ColSpanConfig } from './column-span' import { healVirtualColumnsForRow, getColumnSpanByRowId } from './column-span' import type { VirtualItem } from '@tanstack/react-virtual' describe('getColumnSpanByRowId', () => { it('should return null if no colSpanFunctions are provided', () => { const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col1', 'col2', 'col3'], stickyColumnIds: { left: new Set(), right: new Set() }, colSpanFunctions: [], }) expect(result).toBeNull() }) it('should calculate column spans correctly', () => { const colSpanFunctions = [ { sourceColumn: 'col1', colSpan: ['col1', 'col2'], }, ] const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col1', 'col2', 'col3'], stickyColumnIds: { left: new Set(), right: new Set() }, colSpanFunctions, }) expect(result).toEqual( new Map([ [ 'col1', { id: 'col1', as: undefined, positionColumnIds: ['col1', 'col2'], }, ], [ 'col2', { id: 'col2', skip: true, }, ], ]) ) }) it('should handle sticky columns correctly (left)', () => { const colSpanFunctions = [ { sourceColumn: 'col1', colSpan: ['col1', 'col2', 'col3'], }, ] const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col1', 'col2', 'col3'], stickyColumnIds: { left: new Set(['col1', 'col2']), right: new Set(), }, colSpanFunctions, }) expect(result).toEqual( new Map([ [ 'col1', { id: 'col1', as: undefined, positionColumnIds: ['col1', 'col2'], }, ], [ 'col2', { id: 'col2', skip: true, }, ], ]) ) }) it('should handle sticky columns correctly (right)', () => { const colSpanFunctions = [ { sourceColumn: 'col2', colSpan: ['col1', 'col2', 'col3'], }, ] const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col1', 'col2', 'col3'], stickyColumnIds: { left: new Set([]), right: new Set(['col2', 'col3']), }, colSpanFunctions, }) expect(result).toEqual( new Map([ [ 'col2', { id: 'col2', as: undefined, positionColumnIds: ['col2', 'col3'], }, ], [ 'col3', { id: 'col3', skip: true, }, ], ]) ) }) it('should handle sticky columns correctly (middle)', () => { const colSpanFunctions = [ { sourceColumn: 'col2', colSpan: ['col1', 'col2', 'col3'], }, ] const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col1', 'col2', 'col3'], stickyColumnIds: { left: new Set(['col1']), right: new Set(['col3']), }, colSpanFunctions, }) expect(result).toEqual(null) }) it('should skip columns if they are not in the columnIds list', () => { const colSpanFunctions = [ { sourceColumn: 'col1', colSpan: ['col1', 'col4'], }, ] const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col4', 'col2', 'col3'], stickyColumnIds: { left: new Set(), right: new Set() }, colSpanFunctions, }) expect(result).toEqual( new Map([ [ 'col4', { id: 'col4', as: 'col1', positionColumnIds: ['col4'], }, ], ]) ) }) it('should handle overlapping spans correctly', () => { const colSpanFunctions = [ { sourceColumn: 'col1', colSpan: ['col1', 'col2'], }, { sourceColumn: 'col2', colSpan: ['col2', 'col3'], }, ] const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col1', 'col2', 'col3'], stickyColumnIds: { left: new Set(), right: new Set() }, colSpanFunctions, }) expect(result).toEqual( new Map([ [ 'col1', { id: 'col1', as: undefined, positionColumnIds: ['col1', 'col2'], }, ], [ 'col2', { id: 'col2', skip: true, }, ], [ 'col3', { id: 'col3', as: 'col2', positionColumnIds: ['col3'], }, ], ]) ) }) it('should include the source column if not explicitly included', () => { const colSpanFunctions = [ { sourceColumn: 'col1', colSpan: ['col2'], }, ] const result = getColumnSpanByRowId({ row: { id: '1' }, rowMeta: {}, columnIds: ['col1', 'col2', 'col3'], stickyColumnIds: { left: new Set(), right: new Set() }, colSpanFunctions, }) expect(result).toEqual( new Map([ [ 'col1', { id: 'col1', as: undefined, positionColumnIds: ['col1', 'col2'], }, ], [ 'col2', { id: 'col2', skip: true, }, ], ]) ) }) }) describe('healVirtualColumnsForRow', () => { it('should adjust virtual columns based on colSpanConfig', () => { const virtualColumns: VirtualItem[] = [ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 1, key: 1, start: 50, size: 50, end: 100, lane: 0 }, { index: 2, key: 2, start: 100, size: 50, end: 150, lane: 0 }, ] const colSpanConfig: ColSpanConfig = new Map([ [ 'col1', { id: 'col1', positionColumnIds: ['col1', 'col2'], }, ], [ 'col2', { id: 'col2', skip: true, }, ], ]) const columnIds = ['col1', 'col2', 'col3'] const columnWidths = [50, 50, 50] const result = healVirtualColumnsForRow({ virtualColumns, colSpanConfig, columnIds, columnWidths, }) expect(result).toEqual([ { index: 0, key: 0, start: 0, size: 100, end: 100, lane: 0 }, { index: 2, key: 2, start: 100, size: 50, end: 150, lane: 0 }, ]) }) it('should insert new columns and merge columns if source column is missing', () => { const virtualColumns: VirtualItem[] = [ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 3, key: 3, start: 450, size: 50, end: 500, lane: 0 }, { index: 4, key: 4, start: 500, size: 50, end: 550, lane: 0 }, { index: 5, key: 5, start: 550, size: 50, end: 600, lane: 0 }, ] const colSpanConfig: ColSpanConfig = new Map([ [ 'col2', { id: 'col2', positionColumnIds: ['col2', 'col3', 'col4', 'col5'], }, ], [ 'col3', { id: 'col3', skip: true, }, ], [ 'col4', { id: 'col4', skip: true, }, ], [ 'col5', { id: 'col5', skip: true, }, ], ]) const columnIds = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6'] const columnWidths = [50, 200, 200, 50, 50, 50] const result = healVirtualColumnsForRow({ virtualColumns, colSpanConfig, columnIds, columnWidths, }) expect(result).toEqual([ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 1, key: 1, start: 50, size: 500, end: 550, lane: 0 }, { index: 5, key: 5, start: 550, size: 50, end: 600, lane: 0 }, ]) }) it('should not insert new columns if all referenced columns are not rendered', () => { const virtualColumns: VirtualItem[] = [ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 3, key: 3, start: 450, size: 50, end: 500, lane: 0 }, { index: 4, key: 4, start: 500, size: 50, end: 550, lane: 0 }, { index: 5, key: 5, start: 550, size: 50, end: 600, lane: 0 }, ] const colSpanConfig: ColSpanConfig = new Map([ [ 'col2', { id: 'col2', positionColumnIds: ['col2', 'col3'], }, ], [ 'col3', { id: 'col3', skip: true, }, ], ]) const columnIds = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6'] const columnWidths = [50, 200, 200, 50, 50, 50] const result = healVirtualColumnsForRow({ virtualColumns, colSpanConfig, columnIds, columnWidths, }) expect(result).toEqual([ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 3, key: 3, start: 450, size: 50, end: 500, lane: 0 }, { index: 4, key: 4, start: 500, size: 50, end: 550, lane: 0 }, { index: 5, key: 5, start: 550, size: 50, end: 600, lane: 0 }, ]) }) it('should properly handle if all columns are already rendered', () => { const virtualColumns: VirtualItem[] = [ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 1, key: 1, start: 50, size: 200, end: 250, lane: 0 }, { index: 2, key: 2, start: 250, size: 200, end: 450, lane: 0 }, { index: 3, key: 3, start: 450, size: 50, end: 500, lane: 0 }, { index: 4, key: 4, start: 500, size: 50, end: 550, lane: 0 }, { index: 5, key: 5, start: 550, size: 50, end: 600, lane: 0 }, ] const colSpanConfig: ColSpanConfig = new Map([ [ 'col2', { id: 'col2', positionColumnIds: ['col2', 'col3'], }, ], [ 'col3', { id: 'col3', skip: true, }, ], ]) const columnIds = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6'] const columnWidths = [50, 200, 200, 50, 50, 50] const result = healVirtualColumnsForRow({ virtualColumns, colSpanConfig, columnIds, columnWidths, }) expect(result).toEqual([ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 1, key: 1, start: 50, size: 400, end: 450, lane: 0 }, { index: 3, key: 3, start: 450, size: 50, end: 500, lane: 0 }, { index: 4, key: 4, start: 500, size: 50, end: 550, lane: 0 }, { index: 5, key: 5, start: 550, size: 50, end: 600, lane: 0 }, ]) }) it('should properly handle multiple merges if all columns are already rendered', () => { const virtualColumns: VirtualItem[] = [ { index: 0, start: 0, size: 36, end: 36, key: 0, lane: 0 }, { index: 1, start: 36, size: 100, end: 136, key: 1, lane: 0 }, { index: 2, start: 136, size: 100, end: 236, key: 2, lane: 0 }, { index: 3, start: 236, size: 150, end: 386, key: 3, lane: 0 }, { index: 4, start: 386, size: 150, end: 536, key: 4, lane: 0 }, ] const colSpanConfig: ColSpanConfig = new Map( new Map([ [ 'firstName', { id: 'firstName', positionColumnIds: ['firstName', 'lastName'], }, ], [ 'lastName', { id: 'lastName', skip: true, }, ], [ 'skill', { id: 'skill', positionColumnIds: ['skill', 'skillDetails'], }, ], [ 'skillDetails', { id: 'skillDetails', skip: true, }, ], ]) ) const columnIds = [ '__selection', 'firstName', 'lastName', 'skill', 'skillDetails', ] const columnWidths = [36, 100, 100, 150, 150] const result = healVirtualColumnsForRow({ virtualColumns, colSpanConfig, columnIds, columnWidths, }) expect(result).toEqual([ { index: 0, start: 0, size: 36, end: 36, key: 0, lane: 0 }, { index: 1, start: 36, size: 200, end: 236, key: 1, lane: 0 }, { index: 3, start: 236, size: 300, end: 536, key: 3, lane: 0 }, ]) }) it('should return the same virtual columns if no colSpanConfig is provided', () => { const virtualColumns: VirtualItem[] = [ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 1, key: 1, start: 50, size: 50, end: 100, lane: 0 }, { index: 2, key: 2, start: 100, size: 50, end: 150, lane: 0 }, ] const colSpanConfig: ColSpanConfig = new Map() const columnIds = ['col1', 'col2', 'col3'] const columnWidths = [50, 50, 50] const result = healVirtualColumnsForRow({ virtualColumns, colSpanConfig, columnIds, columnWidths, }) expect(result).toBe(virtualColumns) }) it('should handle cases where colSpanConfig has no positionColumnIds', () => { const virtualColumns: VirtualItem[] = [ { index: 0, key: 0, start: 0, size: 50, end: 50, lane: 0 }, { index: 1, key: 1, start: 50, size: 50, end: 100, lane: 0 }, { index: 2, key: 2, start: 100, size: 50, end: 150, lane: 0 }, ] const colSpanConfig: ColSpanConfig = new Map([ [ 'col1', { id: 'col1', }, ], ]) const columnIds = ['col1', 'col2', 'col3'] const columnWidths = [50, 50, 50] const result = healVirtualColumnsForRow({ virtualColumns, colSpanConfig, columnIds, columnWidths, }) expect(result).toEqual(virtualColumns) }) })