igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
983 lines (799 loc) • 85.9 kB
text/typescript
import { TestBed, ComponentFixture, waitForAsync, fakeAsync, tick } from '@angular/core/testing';
import { IgxGridComponent } from './grid.component';
import { DebugElement, QueryList } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { IgxColumnComponent } from '../columns/column.component';
import { IgxColumnGroupComponent } from '../columns/column-group.component';
import { By } from '@angular/platform-browser';
import { DefaultSortingStrategy, SortingDirection } from '../../data-operations/sorting-strategy';
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
import { configureTestSuite } from '../../test-utils/configure-suite';
import { IgxGridHeaderComponent } from '../headers/grid-header.component';
import { GridSummaryFunctions, GridFunctions } from '../../test-utils/grid-functions.spec';
import { wait } from '../../test-utils/ui-interactions.spec';
import { DropPosition } from '../moving/moving.service';
import { OneGroupOneColGridComponent, OneGroupThreeColsGridComponent,
BlueWhaleGridComponent, ColumnGroupTestComponent, ColumnGroupFourLevelTestComponent,
ThreeGroupsThreeColumnsGridComponent,
NestedColGroupsGridComponent, StegosaurusGridComponent,
OneColPerGroupGridComponent, NestedColumnGroupsGridComponent,
DynamicGridComponent, NestedColGroupsWithTemplatesGridComponent,
DynamicColGroupsGridComponent } from '../../test-utils/grid-mch-sample.spec';
import { CellType } from '../common/grid.interface';
const GRID_COL_THEAD_TITLE_CLASS = 'igx-grid-th__title';
const GRID_COL_GROUP_THEAD_TITLE_CLASS = 'igx-grid-thead__title';
const GRID_COL_GROUP_THEAD_GROUP_CLASS = 'igx-grid-thead__group';
/* eslint-disable max-len */
describe('IgxGrid - multi-column headers #grid', () => {
let fixture: ComponentFixture<any>; let grid: IgxGridComponent; let componentInstance;
configureTestSuite();
beforeAll(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
NoopAnimationsModule,
OneGroupOneColGridComponent,
OneGroupThreeColsGridComponent,
BlueWhaleGridComponent,
ColumnGroupTestComponent,
ColumnGroupFourLevelTestComponent,
ThreeGroupsThreeColumnsGridComponent,
NestedColGroupsGridComponent,
StegosaurusGridComponent,
OneColPerGroupGridComponent,
NestedColumnGroupsGridComponent,
DynamicGridComponent,
NestedColGroupsWithTemplatesGridComponent,
DynamicColGroupsGridComponent
]
})
.compileComponents();
}));
describe('Initialization and rendering tests: ', () => {
it('should initialize a grid with column groups', () => {
fixture = TestBed.createComponent(ColumnGroupTestComponent);
fixture.detectChanges();
grid = fixture.componentInstance.grid;
const expectedColumnGroups = 5;
const expectedLevel = 2;
const groupHeaders = GridFunctions.getColumnGroupHeaders(fixture);
expect(groupHeaders.length).toEqual(expectedColumnGroups);
expect(grid.getColumnByName('ContactName').level).toEqual(expectedLevel);
});
it('Should render column group headers correctly.', fakeAsync(() => {
fixture = TestBed.createComponent(BlueWhaleGridComponent);
fixture.detectChanges();
componentInstance = fixture.componentInstance;
grid = componentInstance.grid;
const columnWidthPx = parseInt(componentInstance.columnWidth, 10);
// 2 levels of column group and 1 level of columns
const gridHeadersDepth = 3;
const firstGroupChildrenCount = 100;
const secondGroupChildrenCount = 2;
const secondSubGroupChildrenCount = 50;
const secondSubGroupHeadersDepth = 2;
const firstGroup = GridFunctions.getColumnGroupHeaders(fixture)[0];
testColumnGroupHeaderRendering(firstGroup, firstGroupChildrenCount * columnWidthPx,
gridHeadersDepth * grid.defaultRowHeight, componentInstance.firstGroupTitle,
'firstGroupColumn', firstGroupChildrenCount);
let horizontalScroll = grid.headerContainer.getScroll();
let scrollToNextGroup = firstGroupChildrenCount * columnWidthPx + columnWidthPx;
horizontalScroll.scrollLeft = scrollToNextGroup;
tick();
fixture.detectChanges();
const secondGroup = GridFunctions.getColumnGroupHeaders(fixture)[1];
testColumnGroupHeaderRendering(secondGroup,
secondGroupChildrenCount * secondSubGroupChildrenCount * columnWidthPx,
gridHeadersDepth * grid.defaultRowHeight, componentInstance.secondGroupTitle,
'secondSubGroup', 0);
const secondSubGroups = secondGroup.queryAll(By.css('.secondSubGroup'));
testColumnGroupHeaderRendering(secondSubGroups[0],
secondSubGroupChildrenCount * columnWidthPx,
secondSubGroupHeadersDepth * grid.defaultRowHeight, componentInstance.secondSubGroupTitle,
'secondSubGroupColumn', secondSubGroupChildrenCount);
testColumnGroupHeaderRendering(secondSubGroups[1],
secondSubGroupChildrenCount * columnWidthPx,
secondSubGroupHeadersDepth * grid.defaultRowHeight, componentInstance.secondSubGroupTitle,
'secondSubGroupColumn', secondSubGroupChildrenCount);
horizontalScroll = grid.headerContainer.getScroll();
scrollToNextGroup = horizontalScroll.scrollLeft +
secondSubGroupHeadersDepth * secondSubGroupChildrenCount * columnWidthPx;
horizontalScroll.scrollLeft = scrollToNextGroup;
tick();
fixture.detectChanges();
const idColumn = fixture.debugElement.query(By.css('.lonelyId'));
testColumnHeaderRendering(idColumn, columnWidthPx,
gridHeadersDepth * grid.defaultRowHeight, componentInstance.idHeaderTitle);
const companyNameColumn = GridFunctions.getColumnHeader('CompanyName', fixture);
testColumnHeaderRendering(companyNameColumn, columnWidthPx,
2 * grid.defaultRowHeight, componentInstance.companyNameTitle);
const personDetailsColumn = GridFunctions.getColumnGroupHeader('Person Details', fixture);
testColumnGroupHeaderRendering(personDetailsColumn, 2 * columnWidthPx,
2 * grid.defaultRowHeight, componentInstance.personDetailsTitle,
'personDetailsColumn', 2);
}));
it('Should render dynamic column group header correctly (#12165).', () => {
fixture = TestBed.createComponent(BlueWhaleGridComponent) as ComponentFixture<BlueWhaleGridComponent>;
(fixture as ComponentFixture<BlueWhaleGridComponent>).componentInstance.firstGroupRepeats = 1;
(fixture as ComponentFixture<BlueWhaleGridComponent>).componentInstance.secondGroupRepeats = 1;
fixture.detectChanges();
componentInstance = fixture.componentInstance;
grid = componentInstance.grid;
const columnWidthPx = parseInt(componentInstance.columnWidth, 10);
// 2 levels of column group and 1 level of columns
const gridHeadersDepth = 3;
let firstGroupChildrenCount = 1;
let firstGroup = GridFunctions.getColumnGroupHeaders(fixture)[0];
testColumnGroupHeaderRendering(firstGroup, firstGroupChildrenCount * columnWidthPx,
gridHeadersDepth * grid.defaultRowHeight, componentInstance.firstGroupTitle,
'firstGroupColumn', firstGroupChildrenCount);
let allHeaders = GridFunctions.getColumnHeaders(fixture).map<IgxGridHeaderComponent>(x => x.componentInstance);
let firstSixHeaders = allHeaders.slice(0, 6).map(x => x.column.field);
expect(allHeaders.length).toEqual(14);
expect(firstSixHeaders).toEqual(['ID', 'ID', 'ID', 'ID', 'CompanyName', 'ContactName']);
(componentInstance as BlueWhaleGridComponent).extraMissingColumn = true;
fixture.detectChanges();
firstGroupChildrenCount = 2;
firstGroup = GridFunctions.getColumnGroupHeaders(fixture)[0];
testColumnGroupHeaderRendering(firstGroup, firstGroupChildrenCount * columnWidthPx,
gridHeadersDepth * grid.defaultRowHeight, componentInstance.firstGroupTitle,
'firstGroupColumn', firstGroupChildrenCount);
allHeaders = GridFunctions.getColumnHeaders(fixture).map<IgxGridHeaderComponent>(x => x.componentInstance);
firstSixHeaders = allHeaders.slice(0, 6).map(x => x.column.field);
expect(allHeaders.length).toEqual(15);
expect(firstSixHeaders).toEqual(['ID', 'Missing', 'ID', 'ID', 'ID', 'CompanyName']);
});
it('Should not render empty column group.', () => {
fixture = TestBed.createComponent(ColumnGroupTestComponent);
fixture.detectChanges();
const ci = fixture.componentInstance;
// Empty column group should not be displayed
const emptyColGroup = GridFunctions.getColumnGroupHeader('Empty Header', fixture);
expect(parseInt(ci.emptyColGroup.width, 10)).toBe(0);
expect(emptyColGroup).toBeUndefined();
});
it('Should render headers correctly when having a column per group.', () => {
fixture = TestBed.createComponent(OneColPerGroupGridComponent);
fixture.detectChanges();
const ci = fixture.componentInstance;
grid = ci.grid;
const addressColGroup = GridFunctions.getColumnGroupHeader('Address Group', fixture);
const addressColGroupDepth = 2; // one-level children
const addressColGroupChildrenCount = 1;
testColumnGroupHeaderRendering(addressColGroup, parseInt(ci.columnWidth, 10),
addressColGroupDepth * grid.defaultRowHeight, ci.addressColGroupTitle,
'addressCol', addressColGroupChildrenCount);
const addressCol = GridFunctions.getColumnHeader('Address', fixture);
testColumnHeaderRendering(addressCol, parseInt(ci.columnWidth, 10),
grid.defaultRowHeight, ci.addressColTitle);
const phoneColGroup = GridFunctions.getColumnGroupHeader('Phone Group', fixture);
const phoneColGroupDepth = 2; // one-level children
const phoneColGroupChildrenCount = 1;
testColumnGroupHeaderRendering(phoneColGroup, parseInt(ci.phoneColWidth, 10),
phoneColGroupDepth * grid.defaultRowHeight, ci.phoneColGroupTitle,
'phoneCol', phoneColGroupChildrenCount);
const phoneCol = GridFunctions.getColumnHeader('Phone', fixture);
testColumnHeaderRendering(phoneCol, parseInt(ci.phoneColWidth, 10),
grid.defaultRowHeight, ci.phoneColTitle);
const faxColGroup = GridFunctions.getColumnGroupHeader('Fax Group', fixture);
const faxColGroupDepth = 2; // one-level children
const faxColGroupChildrenCount = 1;
testColumnGroupHeaderRendering(faxColGroup, parseInt(ci.faxColWidth, 10),
faxColGroupDepth * grid.defaultRowHeight, ci.faxColGroupTitle, 'faxCol',
faxColGroupChildrenCount);
const faxCol = GridFunctions.getColumnHeader('Fax', fixture);
testColumnHeaderRendering(faxCol, parseInt(ci.faxColWidth, 10),
grid.defaultRowHeight, ci.faxColTitle);
});
it('Should render headers correctly when having nested column groups.', () => {
fixture = TestBed.createComponent(NestedColumnGroupsGridComponent);
fixture.detectChanges();
NestedColGroupsTests.testHeadersRendering(fixture);
});
it('Should render headers correctly when having nested column groups with huge header text.', () => {
fixture = TestBed.createComponent(NestedColumnGroupsGridComponent);
fixture.detectChanges();
const ci = fixture.componentInstance;
grid = ci.grid;
const title = 'Lorem Ipsum is simply dummy text of the printing and typesetting' +
' industry.Lorem Ipsum has been the industry\'s standard dummy text ever since' +
' the 1500s, when an unknown printer took a galley of type and scrambled it to' +
' make a type specimen book. It has survived not only five centuries, but also the' +
' leap into electronic typesetting, remaining essentially unchanged.It was popularised' +
' in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and' +
' more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.';
ci.masterColGroupTitle = ci.firstSlaveColGroupTitle =
ci.secondSlaveColGroupTitle = ci.addressColTitle = ci.phoneColTitle =
ci.faxColTitle = ci.cityColTitle = title;
fixture.detectChanges();
NestedColGroupsTests.testHeadersRendering(fixture);
});
it('Should correctly initialize column group templates.', () => {
fixture = TestBed.createComponent(NestedColGroupsWithTemplatesGridComponent);
fixture.detectChanges();
const ci = fixture.componentInstance;
const locationColGroup = ci.locationColGroup;
const contactInfoColGroup = ci.contactInfoColGroup;
expect(locationColGroup.headerTemplate).toBeDefined();
expect(contactInfoColGroup.headerTemplate).toBeUndefined();
const headerSpans: DebugElement[] = fixture.debugElement.queryAll(By.css('.col-group-template'));
expect(headerSpans.length).toBe(1);
expect(headerSpans[0].nativeElement.textContent).toMatch('Column group template');
});
it('Should correctly change column group templates dynamically.', () => {
fixture = TestBed.createComponent(NestedColGroupsWithTemplatesGridComponent);
fixture.detectChanges();
componentInstance = fixture.componentInstance;
const locationColGroup = componentInstance.locationColGroup;
const genInfoColGroup = componentInstance.genInfoColGroup;
const headerTemplate = componentInstance.dynamicColGroupTemplate;
locationColGroup.headerTemplate = headerTemplate;
genInfoColGroup.headerTemplate = headerTemplate;
fixture.detectChanges();
let headerSpans: DebugElement[] = fixture.debugElement.queryAll(By.css('.dynamic-col-group-template'));
expect(headerSpans.length).toBe(2);
headerSpans.forEach(headerSpan => {
expect(headerSpan.nativeElement.textContent).toMatch('Dynamic column group template');
});
locationColGroup.headerTemplate = null;
fixture.detectChanges();
headerSpans = fixture.debugElement.queryAll(By.css('.dynamic-col-group-template'));
expect(headerSpans.length).toBe(1);
headerSpans.forEach(headerSpan => {
expect(headerSpan.nativeElement.textContent).toMatch('Dynamic column group template');
});
headerSpans = fixture.debugElement.queryAll(By.css('.col-group-template'));
expect(headerSpans.length).toBe(0);
headerSpans = fixture.debugElement.queryAll(By.css('.' + GRID_COL_GROUP_THEAD_TITLE_CLASS));
expect(headerSpans[1].nativeElement.textContent).toBe('Location');
});
it('There shouldn\'t be any errors when dynamically removing a column group with filtering enabled', () => {
fixture = TestBed.createComponent(DynamicColGroupsGridComponent);
fixture.detectChanges();
grid = fixture.componentInstance.grid;
let columnLength = grid.columnList.length;
let firstColumnGroup = grid.columnList.first;
let expectedColumnName = 'First';
let expectedColumnListLength = 10;
expect(firstColumnGroup.header).toEqual(expectedColumnName);
expect(expectedColumnListLength).toEqual(columnLength);
fixture.componentInstance.columnGroups = fixture.componentInstance.columnGroups.splice(1, fixture.componentInstance.columnGroups.length - 1);
fixture.detectChanges();
fixture.componentInstance.columnGroups = fixture.componentInstance.columnGroups.splice(1, fixture.componentInstance.columnGroups.length - 1);
fixture.detectChanges();
firstColumnGroup = grid.columnList.first;
expectedColumnName = 'Third';
columnLength = grid.columnList.length;
expectedColumnListLength = 3;
expect(firstColumnGroup.header).toEqual(expectedColumnName);
expect(expectedColumnListLength).toEqual(columnLength);
});
it('There shouldn\'t be any errors when dynamically removing or adding a column in column group', () => {
fixture = TestBed.createComponent(DynamicColGroupsGridComponent);
fixture.detectChanges();
grid = fixture.componentInstance.grid;
expect(grid.columnList.length).toEqual(10);
expect(() => {
// Delete column
fixture.componentInstance.columnGroups[0].columns.splice(0, 1);
fixture.detectChanges();
}).not.toThrow();
expect(grid.columnList.length).toEqual(9);
expect(() => {
// Add column
fixture.componentInstance.columnGroups[0].columns.push({ field: 'Fax', type: 'string' });
fixture.detectChanges();
}).not.toThrow();
expect(grid.columnList.length).toEqual(10);
expect(() => {
// Update column
fixture.componentInstance.columnGroups[0].columns[1] = { field: 'City', type: 'string' };
fixture.detectChanges();
}).not.toThrow();
expect(grid.columnList.length).toEqual(10);
});
it('There shouldn\'t be any errors when the grid is grouped by a column that isn\'t defined', () => {
fixture = TestBed.createComponent(ColumnGroupTestComponent);
fixture.componentInstance.hideGroupedColumns = true;
fixture.detectChanges();
grid = fixture.componentInstance.grid;
expect(() => {
grid.groupBy({
fieldName: 'NonExistentFieldName', dir: SortingDirection.Desc, ignoreCase: false,
strategy: DefaultSortingStrategy.instance()
});
fixture.detectChanges();
}).not.toThrow();
});
it('should set title attribute on column group header spans', () => {
fixture = TestBed.createComponent(ColumnGroupTestComponent);
fixture.detectChanges();
grid = fixture.componentInstance.grid;
const generalGroup = grid.columnList.find(c => c.header === 'General Information');
generalGroup.title = 'General Information Title';
fixture.detectChanges();
const headers = fixture.debugElement.queryAll(By.css('.' + GRID_COL_GROUP_THEAD_TITLE_CLASS));
const generalHeader = headers.find(h => h.nativeElement.textContent === 'General Information');
const addressHeader = headers.find(h => h.nativeElement.textContent === 'Address Information');
expect(generalHeader.nativeElement.firstElementChild.title).toBe('General Information Title');
expect(addressHeader.nativeElement.firstElementChild.title).toBe('Address Information');
});
});
describe('Columns widths tests (1 group 1 column) ', () => {
beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(OneGroupOneColGridComponent);
fixture.detectChanges();
componentInstance = fixture.componentInstance;
grid = fixture.componentInstance.grid;
}));
it('Width should be correct. Column group with column. No width.', () => {
grid.ngAfterViewInit();
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
expect(parseInt(locationColGroup.width, 10) + grid.scrollSize).toBe(parseInt(componentInstance.gridWrapperWidthPx, 10));
const cityColumn = grid.getColumnByName('City');
expect(parseInt(cityColumn.width, 10) + grid.scrollSize).toBe(parseInt(componentInstance.gridWrapperWidthPx, 10));
});
it('Width should be correct. Column group with column. Width in px.', () => {
const gridWidth = '600px';
const gridWidthPx = parseInt(gridWidth, 10);
grid.width = gridWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
expect(parseInt(locationColGroup.width, 10) + grid.scrollSize).toBe(gridWidthPx);
const cityColumn = grid.getColumnByName('City');
expect(parseInt(cityColumn.width, 10) + grid.scrollSize).toBe(gridWidthPx);
});
it('Width should be correct. Column group with column. Width in percent.', () => {
const gridWidth = '50%';
grid.width = gridWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
const gridWidthInPx = ((parseInt(gridWidth, 10) / 100) *
parseInt(componentInstance.gridWrapperWidthPx, 10) - grid.scrollSize) + 'px';
expect(locationColGroup.width).toBe(gridWidthInPx);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(gridWidthInPx);
});
it('Width should be correct. Column group with column. Column width in px.', () => {
const gridColWidth = '200px';
grid.columnWidth = gridColWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
expect(locationColGroup.width).toBe(gridColWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(gridColWidth);
});
it('Width should be correct. Column group with column. Column width in percent.', () => {
const gridColWidth = '50%';
grid.columnWidth = gridColWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
const expectedWidth = (grid.calcWidth / 2) + 'px';
expect(locationColGroup.width).toBe(expectedWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(gridColWidth);
});
it('Width should be correct. Column group with column. Column with width in px.', () => {
const columnWidth = '200px';
componentInstance.columnWidth = columnWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
expect(locationColGroup.width).toBe(columnWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(columnWidth);
});
it('Width should be correct. Column group with column. Column with width in percent.', () => {
const columnWidth = '50%';
componentInstance.columnWidth = columnWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
const expectedWidth = (grid.calcWidth / 2) + 'px';
expect(locationColGroup.width).toBe(expectedWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(columnWidth);
});
it('Should not throw exception if multi-column header columns width is set as number', () => {
expect(() => {
const cityColumn = grid.getColumnByName('City');
(cityColumn.width as any) = 55;
fixture.detectChanges();
}).not.toThrow();
});
});
describe('Columns widths tests (1 group 3 columns) ', () => {
beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(OneGroupThreeColsGridComponent);
fixture.detectChanges();
componentInstance = fixture.componentInstance;
grid = fixture.componentInstance.grid;
}));
it('Width should be correct. Column group with three columns. No width.', () => {
const scrWitdh = grid.nativeElement.querySelector('.igx-grid__tbody-scrollbar').getBoundingClientRect().width;
const availableWidth = (parseInt(componentInstance.gridWrapperWidthPx, 10) - scrWitdh).toString();
const locationColGroup = getColGroup(grid, 'Location');
const colWidth = Math.floor(parseInt(availableWidth, 10) / 3);
const colWidthPx = colWidth + 'px';
expect(locationColGroup.width).toBe((Math.round(colWidth) * 3) + 'px');
const countryColumn = grid.getColumnByName('Country');
expect(countryColumn.width).toBe(colWidthPx);
const regionColumn = grid.getColumnByName('Region');
expect(regionColumn.width).toBe(colWidthPx);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(colWidthPx);
});
it('Width should be correct. Column group with three columns. Width in px.', () => {
const gridWidth = '600px';
grid.width = gridWidth;
fixture.detectChanges();
const scrWitdh = grid.nativeElement.querySelector('.igx-grid__tbody-scrollbar').getBoundingClientRect().width;
const gridWidthInPx = parseInt(gridWidth, 10) - scrWitdh;
const colWidth = Math.floor(gridWidthInPx / 3);
const colWidthPx = colWidth + 'px';
const locationColGroup = getColGroup(grid, 'Location');
expect(locationColGroup.width).toBe((Math.round(colWidth) * 3) + 'px');
const countryColumn = grid.getColumnByName('Country');
expect(countryColumn.width).toBe(colWidthPx);
const regionColumn = grid.getColumnByName('Region');
expect(regionColumn.width).toBe(colWidthPx);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(colWidthPx);
});
it('Width should be correct. Column group with three columns. Columns with mixed width - px and percent.', async () => {
const col1 = grid.getColumnByName('Country');
const col2 = grid.getColumnByName('Region');
const col3 = grid.getColumnByName('City');
col1.width = '200px';
col2.width = '20%';
col3.width = '50%';
fixture.detectChanges();
// check group has correct size.
let locationColGroup = getColGroup(grid, 'Location');
let expectedWidth = (200 + Math.floor(grid.calcWidth * 0.7)) + 'px';
expect(locationColGroup.width).toBe(expectedWidth);
// check header and content have same size.
const col1Header = grid.getColumnByName('Country').headerCell.nativeElement;
const cell1 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).first.nativeElement;
expect(col1Header.offsetWidth).toEqual(cell1.offsetWidth);
let col2Header = grid.getColumnByName('Region').headerCell.nativeElement;
let cell2 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1].nativeElement;
expect(col2Header.offsetWidth - cell2.offsetWidth).toBeLessThanOrEqual(1);
let col3Header = grid.getColumnByName('City').headerCell.nativeElement;
let cell3 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[2].nativeElement;
expect(col3Header.offsetWidth).toEqual(cell3.offsetWidth);
// check that if grid is resized, group size is updated.
componentInstance.gridWrapperWidthPx = '500';
fixture.detectChanges();
await wait(100);
fixture.detectChanges();
locationColGroup = getColGroup(grid, 'Location');
expectedWidth = (200 + Math.floor(grid.calcWidth * 0.7)) + 'px';
expect(locationColGroup.width).toBe(expectedWidth);
col2Header = grid.getColumnByName('Region').headerCell.nativeElement;
cell2 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1].nativeElement;
expect(col2Header.offsetWidth - cell2.offsetWidth).toBeLessThanOrEqual(1);
col3Header = grid.getColumnByName('City').headerCell.nativeElement;
cell3 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[2].nativeElement;
expect(col3Header.offsetWidth).toEqual(cell3.offsetWidth);
});
it('Width should be correct. Column group with three columns. Columns with mixed width - px, percent and null.', () => {
const col1 = grid.getColumnByName('Country');
const col2 = grid.getColumnByName('Region');
const col3 = grid.getColumnByName('City');
col1.width = '200px';
col2.width = '20%';
col3.width = null;
fixture.detectChanges();
// check group has correct size. Should fill available space in grid since one column has no width.
const locationColGroup = getColGroup(grid, 'Location');
const expectedWidth = grid.calcWidth - 1 + 'px';
expect(locationColGroup.width).toBe(expectedWidth);
// check header and content have same size.
const col1Header = grid.getColumnByName('Country').headerCell.nativeElement;
const cell1 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[0].nativeElement;
expect(col1Header.offsetWidth).toEqual(cell1.offsetWidth);
const col2Header = grid.getColumnByName('Region').headerCell.nativeElement;
const cell2 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1].nativeElement;
expect(col2Header.offsetWidth - cell2.offsetWidth).toBeLessThanOrEqual(1);
const col3Header = grid.getColumnByName('City').headerCell.nativeElement;
const cell3 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[2].nativeElement;
expect(col3Header.offsetWidth).toEqual(cell3.offsetWidth);
});
it('Width should be correct. Column group with three columns. Width in percent.', () => {
const gridWidth = '50%';
grid.width = gridWidth;
fixture.detectChanges();
const scrWitdh = grid.nativeElement.querySelector('.igx-grid__tbody-scrollbar').getBoundingClientRect().width;
const gridWidthInPx = (parseInt(gridWidth, 10) / 100) *
parseInt(componentInstance.gridWrapperWidthPx, 10) - scrWitdh;
const colWidth = Math.floor(gridWidthInPx / 3);
const colWidthPx = colWidth + 'px';
const locationColGroup = getColGroup(grid, 'Location');
expect(locationColGroup.width).toBe((Math.round(colWidth) * 3) + 'px');
const countryColumn = grid.getColumnByName('Country');
expect(countryColumn.width).toBe(colWidthPx);
const regionColumn = grid.getColumnByName('Region');
expect(regionColumn.width).toBe(colWidthPx);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(colWidthPx);
});
it('Width should be correct. Column group with three columns. Column width in px.', () => {
const gridColWidth = '200px';
grid.columnWidth = gridColWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
const gridWidth = parseInt(gridColWidth, 10) * 3;
expect(locationColGroup.width).toBe(gridWidth + 'px');
const countryColumn = grid.getColumnByName('Country');
expect(countryColumn.width).toBe(gridColWidth);
const regionColumn = grid.getColumnByName('Region');
expect(regionColumn.width).toBe(gridColWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(gridColWidth);
});
it('Width should be correct. Colum group with three columns. Column width in percent.', () => {
const gridColWidth = '20%';
grid.columnWidth = gridColWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
const expectedWidth = (Math.floor(grid.calcWidth * 0.2) * 3) + 'px';
expect(locationColGroup.width).toBe(expectedWidth);
const countryColumn = grid.getColumnByName('Country');
expect(countryColumn.width).toBe(gridColWidth);
const regionColumn = grid.getColumnByName('Region');
expect(regionColumn.width).toBe(gridColWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(gridColWidth);
});
it('Width should be correct. Column group with three columns. Columns with width in px.', () => {
const columnWidth = '200px';
componentInstance.columnWidth = columnWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
const groupWidth = parseInt(columnWidth, 10) * 3;
expect(locationColGroup.width).toBe(groupWidth + 'px');
const countryColumn = grid.getColumnByName('Country');
expect(countryColumn.width).toBe(columnWidth);
const regionColumn = grid.getColumnByName('Region');
expect(regionColumn.width).toBe(columnWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(columnWidth);
});
it('Width should be correct. Column group with three columns. Columns with width in percent.', () => {
const columnWidth = '20%';
componentInstance.columnWidth = columnWidth;
fixture.detectChanges();
const locationColGroup = getColGroup(grid, 'Location');
const expectedWidth = (Math.floor(grid.calcWidth * 0.2) * 3) + 'px';
expect(locationColGroup.width).toBe(expectedWidth);
const countryColumn = grid.getColumnByName('Country');
expect(countryColumn.width).toBe(columnWidth);
const regionColumn = grid.getColumnByName('Region');
expect(regionColumn.width).toBe(columnWidth);
const cityColumn = grid.getColumnByName('City');
expect(cityColumn.width).toBe(columnWidth);
});
});
describe('Column hiding: ', () => {
beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(ColumnGroupFourLevelTestComponent);
fixture.detectChanges();
grid = fixture.componentInstance.grid;
}));
it('column hiding - verify grid after hiding the last column group', async () => {
grid.navigateTo(0, 10);
await wait(100);
fixture.detectChanges();
await wait(250);
fixture.detectChanges();
let headerDisplayContainer = fixture.debugElement.query(By.css('.igx-grid-thead__wrapper >* .igx-display-container'));
let leftOffset = parseInt(headerDisplayContainer.styles.left, 10);
expect(leftOffset).toBeLessThan(-600);
const initialBodyHeight = parseInt(fixture.debugElement.query(By.css('.igx-grid__tbody-content')).styles.height, 10);
const contactInfoGroup = grid.columns.find(c => c.header === 'Contact Information');
const groupWidth = contactInfoGroup.width;
contactInfoGroup.hidden = true;
fixture.detectChanges();
await wait(200);
fixture.detectChanges();
headerDisplayContainer = fixture.debugElement.query(By.css('.igx-grid-thead__wrapper >* .igx-display-container'));
const expectedOffset = leftOffset - parseInt(groupWidth, 10);
leftOffset = parseInt(headerDisplayContainer.styles.left, 10);
expect(parseInt(fixture.debugElement.query(By.css('.igx-grid__tbody-content')).styles.height, 10)).toEqual(initialBodyHeight);
expect(leftOffset).toBeGreaterThanOrEqual(expectedOffset);
});
it('column hiding - parent level', () => {
const addressGroup = grid.columnList.filter(c => c.header === 'Address Information')[0];
addressGroup.hidden = true;
fixture.detectChanges();
expect(GridFunctions.getColumnHeaders(fixture).length).toEqual(4);
expect(GridFunctions.getColumnGroupHeaders(fixture).length).toEqual(2);
});
it('column hiding - child level', () => {
const addressGroup = fixture.componentInstance.addrInfoColGroup;
addressGroup.children.first.hidden = true;
fixture.detectChanges();
expect(GridFunctions.getColumnGroupHeaders(fixture).length).toEqual(5);
expect(addressGroup.children.first.hidden).toBe(true);
expect(addressGroup.children.first.children.toArray().every(c => c.hidden === true)).toEqual(true);
});
it('column hiding - Verify column hiding of Individual column and Child column', () => {
testGroupsAndColumns(7, 11, fixture);
// Hide individual column
grid.getColumnByName('ID').hidden = true;
fixture.detectChanges();
testGroupsAndColumns(7, 10, fixture);
// Hide column in goup
grid.getColumnByName('CompanyName').hidden = true;
fixture.detectChanges();
expect(GridFunctions.getColumnGroupHeaders(fixture).length).toEqual(7);
expect(GridFunctions.getColumnHeaders(fixture).length).toEqual(9);
grid.getColumnByName('Address').hidden = true;
fixture.detectChanges();
testGroupsAndColumns(7, 8, fixture);
});
it('column hiding - Verify when 2 of 2 child columns are hidden, the Grouped column would be hidden as well.', () => {
testGroupsAndColumns(7, 11, fixture);
// Hide 2 columns in the group
grid.getColumnByName('ContactName').hidden = true;
fixture.detectChanges();
grid.getColumnByName('ContactTitle').hidden = true;
fixture.detectChanges();
testGroupsAndColumns(6, 9, fixture);
expect(getColGroup(grid, 'Person Details').hidden).toEqual(true);
// Show one of the columns
grid.getColumnByName('ContactName').hidden = false;
fixture.detectChanges();
testGroupsAndColumns(7, 10, fixture);
expect(getColGroup(grid, 'Person Details').hidden).toEqual(false);
});
it('column hiding - Verify when 1 child column and 1 group are hidden, the Grouped column would be hidden as well.', () => {
testGroupsAndColumns(7, 11, fixture);
// Hide 2 columns in the group
grid.getColumnByName('CompanyName').hidden = true;
fixture.detectChanges();
getColGroup(grid, 'Person Details').hidden = true;
fixture.detectChanges();
testGroupsAndColumns(5, 8, fixture);
expect(getColGroup(grid, 'General Information').hidden).toEqual(true);
// Show the group
getColGroup(grid, 'Person Details').hidden = false;
fixture.detectChanges();
testGroupsAndColumns(7, 10, fixture);
expect(getColGroup(grid, 'General Information').hidden).toEqual(false);
});
});
describe('API methods tests ', () => {
beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(ColumnGroupFourLevelTestComponent);
fixture.detectChanges();
grid = fixture.componentInstance.grid;
}));
it('API method level should return correct values', () => {
grid.getColumnByName('Fax').hidden = true;
fixture.detectChanges();
getColGroup(grid, 'Person Details').hidden = true;
fixture.detectChanges();
expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7);
// Get level of column
expect(grid.getColumnByName('ID').level).toEqual(0);
expect(grid.getColumnByName('CompanyName').level).toEqual(1);
expect(grid.getColumnByName('Country').level).toEqual(2);
expect(grid.getColumnByName('City').level).toEqual(3);
expect(grid.getColumnByName('PostalCode').level).toEqual(2);
// Get level of hidden column
expect(grid.getColumnByName('Fax').level).toEqual(2);
// Get level of column in hidden group
expect(grid.getColumnByName('ContactTitle').level).toEqual(2);
// Get level of grouped column
expect(getColGroup(grid, 'General Information').level).toEqual(0);
expect(getColGroup(grid, 'Location').level).toEqual(1);
expect(getColGroup(grid, 'Location City').level).toEqual(2);
expect(getColGroup(grid, 'Contact Information').level).toEqual(1);
expect(getColGroup(grid, 'Postal Code').level).toEqual(1);
// Get level of hidden group
expect(getColGroup(grid, 'Person Details').level).toEqual(1);
});
it('API method columnGroup should return correct values', () => {
grid.getColumnByName('Fax').hidden = true;
fixture.detectChanges();
getColGroup(grid, 'Person Details').hidden = true;
fixture.detectChanges();
expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7);
// Get columnGroup of column
expect(grid.getColumnByName('ID').columnGroup).toEqual(false);
expect(grid.getColumnByName('Fax').columnGroup).toEqual(false);
expect(grid.getColumnByName('ContactTitle').columnGroup).toEqual(false);
// Get columnGroup of grouped column
expect(getColGroup(grid, 'General Information').columnGroup).toEqual(true);
expect(getColGroup(grid, 'Location City').columnGroup).toEqual(true);
expect(getColGroup(grid, 'Contact Information').columnGroup).toEqual(true);
expect(getColGroup(grid, 'Postal Code').columnGroup).toEqual(true);
expect(getColGroup(grid, 'Person Details').columnGroup).toEqual(true);
});
it('API method allChildren should return correct values', () => {
grid.getColumnByName('Fax').hidden = true;
fixture.detectChanges();
getColGroup(grid, 'Person Details').hidden = true;
fixture.detectChanges();
expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7);
// Get allChildren of column
expect(grid.getColumnByName('ID').allChildren.length).toEqual(0);
expect(grid.getColumnByName('PostalCode').allChildren.length).toEqual(0);
// Get allChildren of hidden column
expect(grid.getColumnByName('Fax').allChildren.length).toEqual(0);
// Get allChildren of group
const genInfGroupedColumnAllChildren = getColGroup(grid, 'General Information').allChildren;
expect(genInfGroupedColumnAllChildren.length).toEqual(4);
expect(genInfGroupedColumnAllChildren.indexOf(getColGroup(grid, 'Person Details'))).toBeGreaterThanOrEqual(0);
// Get allChildren of hidden group
expect(getColGroup(grid, 'Person Details').allChildren.length).toEqual(2);
// Get allChildren of group with one column
const postCodeGroupedColumnAllChildren = getColGroup(grid, 'Postal Code').allChildren;
expect(postCodeGroupedColumnAllChildren.length).toEqual(1);
expect(postCodeGroupedColumnAllChildren.indexOf(grid.getColumnByName('PostalCode'))).toEqual(0);
// Get allChildren of group with hidden columns and more levels
const addressGroupedColumnAllChildren = getColGroup(grid, 'Address Information').allChildren;
expect(addressGroupedColumnAllChildren.length).toEqual(11);
expect(addressGroupedColumnAllChildren.indexOf(getColGroup(grid, 'Postal Code'))).toBeGreaterThanOrEqual(0);
expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('PostalCode'))).toBeGreaterThanOrEqual(0);
expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('Address'))).toBeGreaterThanOrEqual(0);
expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('Country'))).toBeGreaterThanOrEqual(0);
expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('Fax'))).toBeGreaterThanOrEqual(0);
expect(addressGroupedColumnAllChildren.indexOf(getColGroup(grid, 'General Information'))).toEqual(-1);
});
it('API method children should return correct values', () => {
grid.getColumnByName('Fax').hidden = true;
fixture.detectChanges();
getColGroup(grid, 'Person Details').hidden = true;
fixture.detectChanges();
expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7);
// Get children of grouped column
expect(getColGroup(grid, 'General Information').children.length).toEqual(2);
// Get children of hidden group
expect(getColGroup(grid, 'Person Details').children.length).toEqual(2);
// Get children of group with one column
const postCodeGroupedColumnAllChildren = getColGroup(grid, 'Postal Code').children;
expect(postCodeGroupedColumnAllChildren.length).toEqual(1);
// Get children of group with more levels
const addressGroupedColumnAllChildren = getColGroup(grid, 'Address Information').children;
expect(addressGroupedColumnAllChildren.length).toEqual(3);
});
it('API method topLevelParent should return correct values', () => {
grid.getColumnByName('Fax').hidden = true;
fixture.detectChanges();
getColGroup(grid, 'Person Details').hidden = true;
fixture.detectChanges();
expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7);
// Get topLevelParent of column with no group
expect(grid.getColumnByName('ID').topLevelParent).toBeNull();
// Get topLevelParent of column
const addressGroupedColumn = getColGroup(grid, 'Address Information');
expect(grid.getColumnByName('PostalCode').topLevelParent).toEqual(addressGroupedColumn);
expect(grid.getColumnByName('Fax').topLevelParent).toEqual(addressGroupedColumn);
expect(grid.getColumnByName('Country').topLevelParent).toEqual(addressGroupedColumn);
const genInfGroupedColumn = getColGroup(grid, 'General Information');
expect(grid.getColumnByName('ContactName').topLevelParent).toEqual(genInfGroupedColumn);
expect(grid.getColumnByName('CompanyName').topLevelParent).toEqual(genInfGroupedColumn);
// Get topLevelParent of top group
expect(genInfGroupedColumn.topLevelParent).toBeNull();
expect(addressGroupedColumn.topLevelParent).toBeNull();
// Get topLevelParent of group
expect(getColGroup(grid, 'Person Details').topLevelParent).toEqual(genInfGroupedColumn);
expect(getColGroup(grid, 'Postal Code').topLevelParent).toEqual(addressGroupedColumn);
expect(getColGroup(grid, 'Location City').topLevelParent).toEqual(addressGroupedColumn);
});
it('Should emit "columnInit" event when having multi-column headers.', () => {
fixture = TestBed.createComponent(NestedColumnGroupsGridComponent);
const ci = fixture.componentInstance;
grid = ci.grid;
spyOn(grid.columnInit, 'emit').and.callThrough();
fixture.detectChanges();
const colsCount = 4;
const colGroupsCount = 3;
expect(grid.columnInit.emit).toHaveBeenCalledTimes(colsCount + colGroupsCount);
});
it('Should fire "columnInit" event when adding a multi-column header.', () => {
fixture = TestBed.createComponent(DynamicGridComponent);
componentInstance = fixture.componentInstance;
grid = componentInstance.grid;
fixture.detectChanges();