UNPKG

igniteui-angular-sovn

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,045 lines (862 loc) 169 kB
import { TestBed, fakeAsync, tick, ComponentFixture } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxGridComponent } from './public_api'; import { configureTestSuite } from '../../test-utils/configure-suite'; import { SelectionWithScrollsComponent, SelectionWithTransactionsComponent, CellSelectionNoneComponent, CellSelectionSingleComponent } from '../../test-utils/grid-samples.spec'; import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition'; import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec'; import { clearGridSubs, setupGridScrollDetection } from '../../test-utils/helper-utils.spec'; import { GridSelectionMode } from '../common/enums'; import { GridSelectionFunctions, GridFunctions } from '../../test-utils/grid-functions.spec'; import { DefaultSortingStrategy, SortingDirection } from '../../data-operations/sorting-strategy'; import { DebugElement } from '@angular/core'; import { DropPosition } from '../moving/moving.service'; import { IgxGridGroupByRowComponent } from './groupby-row.component'; describe('IgxGrid - Cell selection #grid', () => { configureTestSuite((() => { return TestBed.configureTestingModule({ imports: [ NoopAnimationsModule, SelectionWithScrollsComponent, SelectionWithTransactionsComponent, CellSelectionNoneComponent, CellSelectionSingleComponent ] }); })); describe('Base', () => { let fix; let grid: IgxGridComponent; let detect; beforeEach(() => { fix = TestBed.createComponent(SelectionWithScrollsComponent); fix.detectChanges(); grid = fix.componentInstance.grid; detect = () => grid.cdr.detectChanges(); }); it('Should be able to select a range with mouse dragging', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const startCell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); const endCell = grid.gridAPI.get_cell_by_index(3, 'ID'); const range = { rowStart: 2, rowEnd: 3, columnStart: 0, columnEnd: 1 }; UIInteractions.simulatePointerOverElementEvent('pointerdown', startCell.nativeElement); detect(); expect(startCell.active).toBe(true); for (let i = 3; i < 5; i++) { const cell = grid.gridAPI.get_cell_by_index(i, grid.columnList.get(i - 1).field); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, i, 1, i - 1); } for (let i = 3; i >= 0; i--) { const cell = grid.gridAPI.get_cell_by_index(i, 'HireDate'); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, i, 1, 3); } for (let i = 2; i >= 0; i--) { const cell = grid.gridAPI.get_cell_by_index(0, grid.columnList.get(i).field); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 0, 1, i); } for (let i = 1; i < 4; i++) { const cell = grid.gridAPI.get_cell_by_index(i, 'ID'); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, i, 1, 0); } UIInteractions.simulatePointerOverElementEvent('pointerup', endCell.nativeElement); detect(); expect(startCell.active).toBe(true); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 3, 1, 0); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(selectionChangeSpy).toHaveBeenCalledWith(range); }); it('Should not lose selection on right clicking', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 2, rowEnd: 3, columnStart: 0, columnEnd: 1 }; grid.setSelection(range); detect(); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 0, 1, 0, 1); // Simulate right-click const endCell = grid.gridAPI.get_cell_by_index(4, 'ID'); UIInteractions.simulateNonPrimaryClick(endCell); detect(); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 0, 1, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); const c = grid.gridAPI.get_cell_by_index(0, 'ID'); UIInteractions.simulateClickAndSelectEvent(c); detect(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifySelectedRange(grid, 0, 0, 0, 0, 0, 1); }); it('Should be able to select multiple ranges with Ctrl key and mouse drag', () => { let firstCell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); let secondCell = grid.gridAPI.get_cell_by_index(2, 'Name'); const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); GridSelectionFunctions.selectCellsRangeNoWait(fix, firstCell, secondCell); detect(); let range = { rowStart: 1, rowEnd: 2, columnStart: 1, columnEnd: 2 }; expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(selectionChangeSpy).toHaveBeenCalledWith(range); expect(grid.selectedCells.length).toBe(4); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2); firstCell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); secondCell = grid.gridAPI.get_cell_by_index(3, 'ID'); GridSelectionFunctions.selectCellsRangeNoWait(fix, firstCell, secondCell, true); detect(); expect(grid.selectedCells.length).toBe(7); range = { rowStart: 2, rowEnd: 3, columnStart: 0, columnEnd: 1 }; expect(selectionChangeSpy).toHaveBeenCalledTimes(2); expect(selectionChangeSpy).toHaveBeenCalledWith(range); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 3, 0, 1); }); it('Should select correct cells with Ctrl key and mouse drag', () => { const range = { rowStart: 3, rowEnd: 2, columnStart: 'Name', columnEnd: 'ParentID' }; const firstCell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); const secondCell = grid.gridAPI.get_cell_by_index(1, 'ID'); const thirdCell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); const expectedData = [ { ParentID: 147, Name: 'Monica Reyes' }, { ParentID: 847, Name: 'Laurence Johnson' }, { ParentID: 147 } ]; grid.selectRange(range); fix.detectChanges(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 3, 1, 2); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 1, 2); UIInteractions.simulatePointerOverElementEvent('pointerdown', firstCell.nativeElement, false, true); detect(); expect(firstCell.active).toBe(true); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 1, 2); UIInteractions.simulatePointerOverElementEvent('pointerenter', secondCell.nativeElement, false, true); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 3, 1, 2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 1, 0, 1); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 1, 2); UIInteractions.simulatePointerOverElementEvent('pointerenter', thirdCell.nativeElement, false, true); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 3, 1, 2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 1); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 1, 2); UIInteractions.simulatePointerOverElementEvent('pointerup', thirdCell.nativeElement); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 3, 1, 2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 1); GridSelectionFunctions.verifyCellSelected(secondCell, false); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 1, 2, 0, 2); GridSelectionFunctions.verifySelectedRange(grid, 1, 2, 1, 1, 1, 2); expect(grid.getSelectedData()).toEqual(expectedData); }); it('Should be able to select multiple cells with Ctrl key and mouse click', () => { const firstCell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); const secondCell = grid.gridAPI.get_cell_by_index(2, 'Name'); const thirdCell = grid.gridAPI.get_cell_by_index(0, 'ID'); const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); UIInteractions.simulateClickAndSelectEvent(firstCell); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifyCellSelected(firstCell); expect(grid.selectedCells.length).toBe(1); UIInteractions.simulateClickAndSelectEvent(secondCell, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifyCellSelected(firstCell); GridSelectionFunctions.verifyCellSelected(secondCell); expect(grid.selectedCells.length).toBe(2); UIInteractions.simulateClickAndSelectEvent(thirdCell, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifyCellSelected(firstCell); GridSelectionFunctions.verifyCellSelected(secondCell); GridSelectionFunctions.verifyCellSelected(thirdCell); expect(grid.selectedCells.length).toBe(3); expect(grid.getSelectedData()).toEqual([{ ParentID: 147 }, { Name: 'Monica Reyes' }, { ID: 475 }]); GridSelectionFunctions.verifySelectedRange(grid, 1, 1, 1, 1, 0, 3); GridSelectionFunctions.verifySelectedRange(grid, 2, 2, 2, 2, 1, 3); GridSelectionFunctions.verifySelectedRange(grid, 0, 0, 0, 0, 2, 3); }); it('Should be able to select cells correctly when focus is returned to the grid', async() => { const firstCell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); const secondCell = grid.gridAPI.get_cell_by_index(2, 'Name'); UIInteractions.simulateClickAndSelectEvent(firstCell); fix.detectChanges(); GridSelectionFunctions.verifyCellSelected(firstCell); expect(grid.selectedCells.length).toBe(1); UIInteractions.simulateClickAndSelectEvent(firstCell, false, true); fix.detectChanges(); expect(grid.selectedCells.length).toBe(0); grid.navigation.lastActiveNode = grid.navigation.activeNode; grid.navigation.activeNode = null; fix.detectChanges(); grid.tbody.nativeElement.focus(); fix.detectChanges(); UIInteractions.simulateClickAndSelectEvent(secondCell, false, true); fix.detectChanges(); GridSelectionFunctions.verifyCellSelected(firstCell, false); GridSelectionFunctions.verifyCellSelected(secondCell, true); expect(grid.selectedCells.length).toBe(1); }); it('Should be able to select range when click on a cell and hold Shift key and click on another Cell', () => { const firstCell = grid.gridAPI.get_cell_by_index(3, 'HireDate'); const secondCell = grid.gridAPI.get_cell_by_index(1, 'ID'); const thirdCell = grid.gridAPI.get_cell_by_index(0, 'Name'); const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); GridSelectionFunctions.selectCellsRangeWithShiftKeyNoWait(fix, firstCell, secondCell); expect(grid.selectedCells.length).toBe(12); let range = { rowStart: 1, rowEnd: 3, columnStart: 0, columnEnd: 3 }; expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(selectionChangeSpy).toHaveBeenCalledWith(range); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 3, 0, 3); GridSelectionFunctions.verifySelectedRange(grid, 1, 3, 0, 3); UIInteractions.simulateClickAndSelectEvent(thirdCell, true); fix.detectChanges(); expect(grid.selectedCells.length).toBe(8); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 3, 2, 3); range = { rowStart: 0, rowEnd: 3, columnStart: 2, columnEnd: 3 }; expect(selectionChangeSpy).toHaveBeenCalledTimes(2); expect(selectionChangeSpy).toHaveBeenCalledWith(range); GridSelectionFunctions.verifySelectedRange(grid, 0, 3, 2, 3); }); it('Should return correct ranges from `getSelectedRanges` on shfit + click in the event handler', () => { const firstCell = grid.gridAPI.get_cell_by_index(3, 'HireDate'); const secondCell = grid.gridAPI.get_cell_by_index(1, 'ID'); const sub = grid.rangeSelected.subscribe(_ => { expect(grid.selectedCells.length).toEqual(12); const range = grid.getSelectedRanges()[0]; GridSelectionFunctions.verifySelectedRange(grid, range.rowStart, range.rowEnd, range.columnStart, range.columnEnd); GridSelectionFunctions.verifySelectedRange(grid, 1, 3, 0, 3); }); GridSelectionFunctions.selectCellsRangeWithShiftKeyNoWait(fix, firstCell, secondCell); sub.unsubscribe(); }); it('Should be able to select range with Shift key when first cell is not visible', (async () => { const firstCell = grid.gridAPI.get_cell_by_index(1, 'ID'); const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const expectedData1 = [ { ID: 957, ParentID: 147 }, { ID: 317, ParentID: 147 }, { ID: 225, ParentID: 847 }, { ID: 663, ParentID: 847 }, { ID: 15, ParentID: 19 }, { ID: 12, ParentID: 17 }, { ID: 101, ParentID: 17 } ]; const expectedData2 = [ { ID: 957, ParentID: 147, Name: 'Thomas Hardy' }, { ID: 317, ParentID: 147, Name: 'Monica Reyes' }, { ID: 225, ParentID: 847, Name: 'Laurence Johnson' }, { ID: 663, ParentID: 847, Name: 'Elizabeth Richards' }, { ID: 15, ParentID: 19, Name: 'Antonio Moreno' }, { ID: 12, ParentID: 17, Name: 'Pedro Afonso' } ]; UIInteractions.simulateClickAndSelectEvent(firstCell); await wait(); fix.detectChanges(); GridSelectionFunctions.verifyCellSelected(firstCell); grid.verticalScrollContainer.scrollTo(grid.dataView.length - 1); await wait(100); fix.detectChanges(); const secondCell = grid.gridAPI.get_cell_by_index(7, 'ParentID'); UIInteractions.simulateClickAndSelectEvent(secondCell, true); await wait(); fix.detectChanges(); let range = { rowStart: 1, rowEnd: 7, columnStart: 0, columnEnd: 1 }; expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(grid.getSelectedData()).toEqual(expectedData1); expect(selectionChangeSpy).toHaveBeenCalledWith(range); expect(grid.getSelectedRanges()).toEqual([range]); GridSelectionFunctions.verifyCellsRegionSelected(grid, 3, 7, 0, 1); const thirdCell = grid.gridAPI.get_cell_by_index(6, 'Name'); UIInteractions.simulateClickAndSelectEvent(thirdCell, true); await wait(); fix.detectChanges(); range = { rowStart: 1, rowEnd: 6, columnStart: 0, columnEnd: 2 }; expect(selectionChangeSpy).toHaveBeenCalledTimes(2); expect(selectionChangeSpy).toHaveBeenCalledWith(range); expect(grid.getSelectedRanges()).toEqual([range]); expect(grid.getSelectedData()).toEqual(expectedData2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 3, 6, 0, 2); grid.verticalScrollContainer.scrollTo(0); await wait(100); fix.detectChanges(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 4, 0, 2); expect(selectionChangeSpy).toHaveBeenCalledTimes(2); expect(grid.getSelectedData()).toEqual(expectedData2); })); it('Should update range selection when hold a Ctrl key and click on another cell', () => { const firstCell = grid.gridAPI.get_cell_by_index(2, 'ID'); const secondCell = grid.gridAPI.get_cell_by_index(0, 'ParentID'); const thirdCell = grid.gridAPI.get_cell_by_index(0, 'Name'); const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const expectedData1 = [ { ID: 475, ParentID: 147 }, { ID: 957, ParentID: 147 }, { ID: 317, ParentID: 147 } ]; const expectedData2 = [ { ID: 475, ParentID: 147, Name: 'Michael Langdon' }, { ID: 957 }, { ID: 317, ParentID: 147 } ]; GridSelectionFunctions.selectCellsRangeWithShiftKeyNoWait(fix, firstCell, secondCell); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(selectionChangeSpy).toHaveBeenCalledWith({ rowStart: 0, rowEnd: 2, columnStart: 0, columnEnd: 1 }); expect(grid.getSelectedData()).toEqual(expectedData1); GridSelectionFunctions.verifySelectedRange(grid, 0, 2, 0, 1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 2, 0, 1); // Click on another cell holding control UIInteractions.simulateClickAndSelectEvent(thirdCell, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); GridSelectionFunctions.verifySelectedRange(grid, 0, 2, 0, 1, 0, 2); GridSelectionFunctions.verifySelectedRange(grid, 0, 0, 2, 2, 1, 2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 2, 0, 1); GridSelectionFunctions.verifyCellSelected(thirdCell); // Click on a cell in the region and verify it is deselected let cell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); UIInteractions.simulateClickAndSelectEvent(cell, false, true); fix.detectChanges(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 0, 0, 2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 2, 0, 1); GridSelectionFunctions.verifyCellSelected(cell, false); GridSelectionFunctions.verifyCellSelected(grid.gridAPI.get_cell_by_index(1, 'ID'), true); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(grid.getSelectedData()).toEqual(expectedData2); // Click on a cell without holding Ctrl cell = grid.gridAPI.get_cell_by_index(0, 'ID'); UIInteractions.simulateClickAndSelectEvent(cell); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(grid.getSelectedData()).toEqual([{ ID: 475 }]); GridSelectionFunctions.verifySelectedRange(grid, 0, 0, 0, 0); GridSelectionFunctions.verifyCellSelected(cell); GridSelectionFunctions.verifyCellSelected(firstCell, false); GridSelectionFunctions.verifyCellSelected(secondCell, false); GridSelectionFunctions.verifyCellSelected(thirdCell, false); }); it('Should not be possible to select a range when change cellSelection to none', () => { const rangeChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const startCell = grid.gridAPI.get_cell_by_index(0, 'Name'); const endCell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); expect(grid.cellSelection).toEqual(GridSelectionMode.multiple); GridSelectionFunctions.selectCellsRangeNoWait(fix, startCell, endCell); detect(); expect(rangeChangeSpy).toHaveBeenCalledTimes(1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 2, 1, 2); GridSelectionFunctions.verifySelectedRange(grid, 0, 2, 1, 2); grid.cellSelection = GridSelectionMode.none; fix.detectChanges(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 2, 1, 2, false); expect(grid.getSelectedData()).toEqual([]); expect(grid.getSelectedRanges()).toEqual([]); // Try to select a range GridSelectionFunctions.selectCellsRangeNoWait(fix, startCell, endCell); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 2, 1, 2, false); expect(rangeChangeSpy).toHaveBeenCalledTimes(1); expect(grid.selectedCells.length).toBe(0); expect(grid.getSelectedData().length).toBe(1); expect(grid.getSelectedRanges()).toEqual([]); }); it('Should not be possible to select a range when change cellSelection to single', () => { const rangeChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const startCell = grid.gridAPI.get_cell_by_index(0, 'ID'); const endCell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); expect(grid.cellSelection).toEqual(GridSelectionMode.multiple); GridSelectionFunctions.selectCellsRangeNoWait(fix, startCell, endCell); detect(); expect(rangeChangeSpy).toHaveBeenCalledTimes(1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 1, 0, 1); GridSelectionFunctions.verifySelectedRange(grid, 0, 1, 0, 1); grid.cellSelection = GridSelectionMode.single; fix.detectChanges(); expect(grid.cellSelection).toEqual(GridSelectionMode.single); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 1, 0, 1, false); expect(grid.getSelectedData()).toEqual([]); expect(grid.getSelectedRanges()).toEqual([]); // Try to select a range UIInteractions.simulatePointerOverElementEvent('pointerdown', endCell.nativeElement); endCell.nativeElement.dispatchEvent(new MouseEvent('click')); fix.detectChanges(); UIInteractions.simulatePointerOverElementEvent('pointerenter', startCell.nativeElement); UIInteractions.simulatePointerOverElementEvent('pointerup', startCell.nativeElement); fix.detectChanges(); detect(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 0, 0, 1, false); expect(rangeChangeSpy).toHaveBeenCalledTimes(1); expect(grid.selectedCells.length).toBe(1); expect(grid.getSelectedData()).toEqual([{ ParentID: 147 }]); GridSelectionFunctions.verifySelectedRange(grid, 1, 1, 1, 1); }); }); describe('API', () => { let fix; let grid; let detect; beforeEach(() => { fix = TestBed.createComponent(SelectionWithScrollsComponent); fix.detectChanges(); grid = fix.componentInstance.grid; detect = () => grid.cdr.detectChanges(); }); it('Should select a single cell', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 2, rowEnd: 2, columnStart: 1, columnEnd: 1 }; const cell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); const expectedData = [ { ParentID: 147 } ]; grid.selectRange(range); fix.detectChanges(); GridSelectionFunctions.verifyCellSelected(cell); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); expect(grid.getSelectedRanges()).toEqual([range]); }); it('Should select a region', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 0, rowEnd: 2, columnStart: 'Name', columnEnd: 'ParentID' }; const expectedData = [ { ParentID: 147, Name: 'Michael Langdon' }, { ParentID: 147, Name: 'Thomas Hardy' }, { ParentID: 147, Name: 'Monica Reyes' } ]; grid.selectRange(range); fix.detectChanges(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 2, 1, 2); GridSelectionFunctions.verifySelectedRange(grid, 0, 2, 1, 2); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); }); it('Should select a region when one of cells is not visible', (async () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 3, rowEnd: 7, columnStart: 'ID', columnEnd: 'ParentID' }; const expectedData = [ { ID: 225, ParentID: 847 }, { ID: 663, ParentID: 847 }, { ID: 15, ParentID: 19 }, { ID: 12, ParentID: 17 }, { ID: 101, ParentID: 17 } ]; grid.selectRange(range); fix.detectChanges(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 3, 4, 0, 1); GridSelectionFunctions.verifySelectedRange(grid, 3, 7, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); grid.verticalScrollContainer.scrollTo(grid.dataView.length - 1); await wait(100); fix.detectChanges(); GridSelectionFunctions.verifyCellsRegionSelected(grid, 4, 7, 0, 1); GridSelectionFunctions.verifySelectedRange(grid, 3, 7, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); })); it('Should select a region when two of cells are not visible', (async () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 6, rowEnd: 6, columnStart: 'OnPTO', columnEnd: 'Age' }; const expectedData = [ { Age: 50, OnPTO: false } ]; grid.selectRange(range); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 6, 6, 4, 5); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); grid.verticalScrollContainer.scrollTo(grid.dataView.length - 1); await wait(100); fix.detectChanges(); grid.dataRowList.first.virtDirRow.scrollTo(5); await wait(100); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 6, 6, 4, 5); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); GridSelectionFunctions.verifyCellsRegionSelected(grid, 6, 6, 4, 5); })); it('Should add new range when there is already added range', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range1 = { rowStart: 0, rowEnd: 1, columnStart: 'ID', columnEnd: 'ParentID' }; const range2 = { rowStart: 1, rowEnd: 2, columnStart: 'ParentID', columnEnd: 'Name' }; const expectedData1 = [ { ID: 475, ParentID: 147 }, { ID: 957, ParentID: 147 } ]; const expectedData2 = [ { ID: 475, ParentID: 147 }, { ID: 957, ParentID: 147, Name: 'Thomas Hardy' }, { ParentID: 147, Name: 'Monica Reyes' } ]; grid.selectRange(range1); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 0, 1, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 1, 0, 1); grid.selectRange(range2); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 0, 1, 0, 1, 0, 2); GridSelectionFunctions.verifySelectedRange(grid, 1, 2, 1, 2, 1, 2); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 1, 0, 1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2); }); it('Should add multiple ranges', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range1 = { rowStart: 0, rowEnd: 0, columnStart: 'ID', columnEnd: 'ParentID' }; const range2 = { rowStart: 2, rowEnd: 3, columnStart: 'ParentID', columnEnd: 'Name' }; const expectedData = [ { ID: 475, ParentID: 147 }, { ParentID: 147, Name: 'Monica Reyes' }, { ParentID: 847, Name: 'Laurence Johnson' } ]; grid.selectRange([range1, range2]); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 0, 0, 0, 1, 0, 2); GridSelectionFunctions.verifySelectedRange(grid, 2, 3, 1, 2, 1, 2); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); GridSelectionFunctions.verifyCellsRegionSelected(grid, 0, 0, 0, 1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 3, 1, 2); }); it('Should add multiple ranges when they have same cells', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range1 = { rowStart: 1, rowEnd: 3, columnStart: 'ID', columnEnd: 'ParentID' }; const range2 = { rowStart: 3, rowEnd: 1, columnStart: 'ParentID', columnEnd: 'ID' }; const expectedData = [ { ID: 957, ParentID: 147 }, { ID: 317, ParentID: 147 }, { ID: 225, ParentID: 847 } ]; grid.selectRange([range1, range2]); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 1, 3, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 3, 0, 1); }); it('Should add multiple ranges when some of their cells are same', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range1 = { rowStart: 1, rowEnd: 3, columnStart: 'ID', columnEnd: 'ParentID' }; const range2 = { rowStart: 4, rowEnd: 2, columnStart: 'ParentID', columnEnd: 'ID' }; const expectedData = [ { ID: 957, ParentID: 147 }, { ID: 317, ParentID: 147 }, { ID: 225, ParentID: 847 }, { ID: 663, ParentID: 847 } ]; grid.selectRange([range1, range2]); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 1, 3, 0, 1, 0, 2); GridSelectionFunctions.verifySelectedRange(grid, 2, 4, 0, 1, 1, 2); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 4, 0, 1); }); it('Should not add range when column is hidden', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 1, rowEnd: 3, columnStart: 'ID', columnEnd: 'Name' }; grid.getColumnByName('Name').hidden = true; fix.detectChanges(); let errorMessage = ''; try { grid.selectRange(range); } catch (error) { errorMessage = error.message; } finally { fix.detectChanges(); } expect(errorMessage).toContain('visibleIndex'); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual([]); expect(grid.getSelectedRanges()).toEqual([]); }); it('Should not add range when column is hidden and there is already selected range', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range1 = { rowStart: 1, rowEnd: 2, columnStart: 'ID', columnEnd: 'Name' }; const range2 = { rowStart: 0, rowEnd: 4, columnStart: 'ParentID', columnEnd: 'OnPTO' }; const expectedData = [ { ID: 957, Name: 'Thomas Hardy' }, { ID: 317, Name: 'Monica Reyes' } ]; grid.getColumnByName('ParentID').hidden = true; fix.detectChanges(); grid.selectRange(range1); fix.detectChanges(); GridSelectionFunctions.verifySelectedRange(grid, 1, 2, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 0, 1); let errorMessage = ''; try { grid.selectRange(range2); } catch (error) { errorMessage = error.message; } finally { fix.detectChanges(); } expect(errorMessage).toContain('visibleIndex'); GridSelectionFunctions.verifySelectedRange(grid, 1, 2, 0, 1); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual(expectedData); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 0, 1); }); it('Should not add range when column does not exist', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 1, rowEnd: 3, columnStart: 'NotExisting', columnEnd: 'Name' }; let errorMessage = ''; try { grid.selectRange(range); } catch (error) { errorMessage = error.message; } finally { fix.detectChanges(); } expect(errorMessage).toContain('visibleIndex'); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedData()).toEqual([]); expect(grid.getSelectedRanges()).toEqual([]); }); it('Should add range when row does not exist', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: -7, rowEnd: 100, columnStart: 'ID', columnEnd: 'ID' }; const expectedData = [ { ID: 475 }, { ID: 957 }, { ID: 317 }, { ID: 225 }, { ID: 663 }, { ID: 15 }, { ID: 12 }, { ID: 101 } ]; grid.selectRange(range); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifySelectedRange(grid, -7, 100, 0, 0); expect(grid.getSelectedData()).toEqual(expectedData); }); it('Should add range when columnStart index does not exist', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 0, rowEnd: 1, columnStart: -4, columnEnd: 0 }; const expectedData = [ { ID: 475 }, { ID: 957 } ]; grid.selectRange(range); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifySelectedRange(grid, 0, 1, -4, 0); expect(grid.getSelectedData()).toEqual(expectedData); }); it('Should add range when columnStart and columnEnd indexes do not exist', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 1, rowEnd: 2, columnStart: 5, columnEnd: 10 }; const expectedData = [ { OnPTO: true }, { OnPTO: false } ]; grid.selectRange(range); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifySelectedRange(grid, 1, 2, 5, 10); expect(grid.getSelectedData()).toEqual(expectedData); }); it('Should not add range when columnStart and columnEnd indexes do not exist', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 1, rowEnd: 2, columnStart: 10, columnEnd: 100 }; grid.selectRange(range); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifySelectedRange(grid, 1, 2, 10, 100); expect(grid.getSelectedData()).toEqual([]); }); it('Should be able to clear the selected ranges', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const range = { rowStart: 1, rowEnd: 2, columnStart: 1, columnEnd: 2 }; const expectedData = [ { ParentID: 147, Name: 'Thomas Hardy' }, { ParentID: 147, Name: 'Monica Reyes' } ]; grid.selectRange(range); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); GridSelectionFunctions.verifySelectedRange(grid, 1, 2, 1, 2); expect(grid.getSelectedData()).toEqual(expectedData); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2); grid.selectRange(); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); expect(grid.getSelectedRanges().length).toEqual(0); expect(grid.getSelectedData()).toEqual([]); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2, false); }); it('Should be able to clear the selection when a single cell is selected', () => { const cell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); UIInteractions.simulateClickAndSelectEvent(cell); fix.detectChanges(); GridSelectionFunctions.verifyCellSelected(cell); GridSelectionFunctions.verifySelectedRange(grid, 1, 1, 1, 1); grid.selectRange(null); fix.detectChanges(); expect(grid.getSelectedRanges().length).toEqual(0); expect(grid.getSelectedData()).toEqual([]); GridSelectionFunctions.verifyCellSelected(cell, false); }); it('Should be able to clear the selection when there are no selected cells', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); grid.selectRange(); fix.detectChanges(); expect(grid.getSelectedRanges().length).toEqual(0); expect(grid.getSelectedData()).toEqual([]); expect(selectionChangeSpy).toHaveBeenCalledTimes(0); }); it('Should return correct selected data when selected event is emitted', () => { let selectedData = []; grid.selected.subscribe(() => { selectedData = grid.getSelectedData(); }); const cell = grid.gridAPI.get_cell_by_index(2, 'Name'); UIInteractions.simulateClickAndSelectEvent(cell); fix.detectChanges(); expect(selectedData.length).toBe(1); expect(selectedData[0]).toEqual({ Name: 'Monica Reyes' }); const idCell = grid.gridAPI.get_cell_by_index(1, 'ID'); UIInteractions.simulateClickAndSelectEvent(idCell, false, true); fix.detectChanges(); expect(selectedData.length).toBe(2); expect(selectedData[0]).toEqual({ Name: 'Monica Reyes' }); expect(selectedData[1]).toEqual({ ID: 957 }); }); it('rangeSelected event should be emitted when pointer leaves active state outside grid\'s cells', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); const startCell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); const range = { rowStart: 2, rowEnd: 3, columnStart: 0, columnEnd: 1 }; UIInteractions.simulatePointerOverElementEvent('pointerdown', startCell.nativeElement); detect(); expect(startCell.active).toBe(true); for (let i = 3; i < 5; i++) { const cell = grid.gridAPI.get_cell_by_index(i, grid.columnList.get(i - 1).field); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); } for (let i = 3; i >= 0; i--) { const cell = grid.gridAPI.get_cell_by_index(i, 'HireDate'); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); } for (let i = 2; i >= 0; i--) { const cell = grid.gridAPI.get_cell_by_index(0, grid.columnList.get(i).field); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); } for (let i = 1; i < 4; i++) { const cell = grid.gridAPI.get_cell_by_index(i, 'ID'); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); } UIInteractions.simulatePointerOverElementEvent('pointerup', document.body); detect(); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); expect(selectionChangeSpy).toHaveBeenCalledWith(range); }); it('Should not throw an error when trying to do a drag selection that is started outside the grid', fakeAsync(() => { const cell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); UIInteractions.simulatePointerOverElementEvent('pointerdown', document.body); tick(); fix.detectChanges(); UIInteractions.simulatePointerOverElementEvent('pointerenter', cell.nativeElement); UIInteractions.simulatePointerOverElementEvent('pointerup', cell.nativeElement); tick(); fix.detectChanges(); expect(() => { fix.detectChanges(); }).not.toThrow(); })); }); describe('Keyboard navigation', () => { let fix: ComponentFixture<any>; let grid; let detect; let gridContent: DebugElement; beforeEach(() => { fix = TestBed.createComponent(SelectionWithScrollsComponent); fix.detectChanges(); grid = fix.componentInstance.grid; gridContent = GridFunctions.getGridContent(fix); setupGridScrollDetection(fix, grid); detect = () => grid.cdr.detectChanges(); }); afterEach(() => { clearGridSubs(); }); it('Should be able to select a range with arrow keys and holding Shift', () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); let cell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); UIInteractions.simulateClickAndSelectEvent(cell); fix.detectChanges(); GridSelectionFunctions.verifyCellSelected(cell); GridSelectionFunctions.verifySelectedRange(grid, 1, 1, 1, 1); UIInteractions.triggerKeyDownEvtUponElem('arrowdown', cell.nativeElement, true, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 1); cell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); UIInteractions.triggerKeyDownEvtUponElem('arrowright', cell.nativeElement, true, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2); cell = grid.gridAPI.get_cell_by_index(2, 'Name'); UIInteractions.triggerKeyDownEvtUponElem('arrowup', cell.nativeElement, true, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(3); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 1, 1, 2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 2, 2, 1, 3, false); cell = grid.gridAPI.get_cell_by_index(1, 'Name'); UIInteractions.triggerKeyDownEvtUponElem('arrowleft', cell.nativeElement, true, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(4); GridSelectionFunctions.verifyCellSelected(cell, false); cell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); GridSelectionFunctions.verifyCellSelected(cell); UIInteractions.triggerKeyDownEvtUponElem('arrowleft', cell.nativeElement, true, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(5); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 1, 0, 1); GridSelectionFunctions.verifySelectedRange(grid, 1, 1, 0, 1); expect(grid.getSelectedData()).toEqual([{ ID: 957, ParentID: 147 }]); }); it(`Should not clear selection from keyboard shift-state on non-primary click`, () => { const selectionChangeSpy = spyOn<any>(grid.rangeSelected, 'emit').and.callThrough(); let cell = grid.gridAPI.get_cell_by_index(1, 'ParentID'); UIInteractions.simulateClickAndSelectEvent(cell); fix.detectChanges(); GridSelectionFunctions.verifyCellSelected(cell); GridSelectionFunctions.verifySelectedRange(grid, 1, 1, 1, 1); UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(1); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 1); cell = grid.gridAPI.get_cell_by_index(2, 'ParentID'); UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent, false, true); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2); UIInteractions.simulateNonPrimaryClick(cell); fix.detectChanges(); expect(selectionChangeSpy).toHaveBeenCalledTimes(2); GridSelectionFunctions.verifyCellsRegionSelected(grid, 1, 2, 1, 2); }); it(`Should not clear range when try to navigate out the grid with shift + arrrow keys and then click on other cell with pressed Ctrl'`, () => { pending('# Issue should be fixedy'); let cell = grid.gridAPI.get_cell_by_index(0, 'ID'); UIInteractions.simulateClickAndSelectEvent(cell); fix.detectChanges(); GridSelectionFunctions.