UNPKG

igniteui-angular-sovn

Version:

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

508 lines (450 loc) 21.3 kB
import { configureTestSuite } from '../test-utils/configure-suite'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { Component, ViewChild, DebugElement } from '@angular/core'; import { SplitterType, IgxSplitterComponent, ISplitterBarResizeEventArgs } from './splitter.component'; import { By } from '@angular/platform-browser'; import { UIInteractions } from '../test-utils/ui-interactions.spec'; import { IgxSplitterPaneComponent } from './splitter-pane/splitter-pane.component'; const SPLITTERBAR_CLASS = 'igx-splitter-bar'; const SPLITTERBAR_DIV_CLASS = '.igx-splitter-bar'; const SPLITTER_BAR_VERTICAL_CLASS = 'igx-splitter-bar--vertical'; describe('IgxSplitter', () => { configureTestSuite(); beforeAll(waitForAsync(() => TestBed.configureTestingModule({ imports: [ SplitterTestComponent ] }).compileComponents())); let fixture; let splitter; beforeEach(waitForAsync(() => { fixture = TestBed.createComponent(SplitterTestComponent); fixture.detectChanges(); splitter = fixture.componentInstance.splitter; })); it('should render pane content correctly in splitter.', () => { expect(splitter.panes.length).toBe(2); const firstPane = splitter.panes.toArray()[0].element; const secondPane = splitter.panes.toArray()[1].element; expect(firstPane.textContent.trim()).toBe('Pane 1'); expect(secondPane.textContent.trim()).toBe('Pane 2'); const splitterBar = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).nativeElement; expect(firstPane.style.order).toBe('0'); expect(splitterBar.style.order).toBe('1'); expect(secondPane.style.order).toBe('2'); }); it('should render vertical splitter.', () => { fixture.componentInstance.type = SplitterType.Vertical; fixture.detectChanges(); const splitterBarDIV = fixture.debugElement.query(By.css(SPLITTERBAR_DIV_CLASS)); const hasVerticalClass = splitterBarDIV.nativeElement.classList.contains(SPLITTER_BAR_VERTICAL_CLASS); expect(hasVerticalClass).toBeFalsy(); }); it('should render horizontal splitter.', () => { const splitterBarDIV = fixture.debugElement.query(By.css(SPLITTERBAR_DIV_CLASS)); const hasVerticalClass = splitterBarDIV.nativeElement.classList.contains(SPLITTER_BAR_VERTICAL_CLASS); expect(hasVerticalClass).toBeTruthy(); }); it('should allow resizing vertical splitter', () => { fixture.componentInstance.type = SplitterType.Vertical; fixture.detectChanges(); const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; expect(pane1.size).toBe('auto'); expect(pane2.size).toBe('auto'); const pane1_originalSize = pane1.element.offsetHeight; const pane2_originalSize = pane2.element.offsetHeight; const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(-100); fixture.detectChanges(); expect(pane1.dragSize).toBe(pane1_originalSize + 100 + 'px'); expect(pane2.dragSize).toBe(pane2_originalSize - 100 + 'px'); splitterBarComponent.moving.emit(100); fixture.detectChanges(); expect(pane1.dragSize).toBe(pane1_originalSize - 100 + 'px'); expect(pane2.dragSize).toBe(pane2_originalSize + 100 + 'px'); }); it('should allow resizing horizontal splitter', () => { const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; expect(pane1.size).toBe('auto'); expect(pane2.size).toBe('auto'); const pane1_originalSize = pane1.element.offsetWidth; const pane2_originalSize = pane2.element.offsetWidth; const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(-100); fixture.detectChanges(); expect(parseFloat(pane1.dragSize)).toBeCloseTo(pane1_originalSize + 100, 0); expect(parseFloat(pane2.dragSize)).toBeCloseTo(pane2_originalSize - 100, 0); splitterBarComponent.moving.emit(100); fixture.detectChanges(); expect(parseFloat(pane1.dragSize)).toBeCloseTo(pane1_originalSize - 100, 0); expect(parseFloat(pane2.dragSize)).toBeCloseTo(pane2_originalSize + 100, 0); }); it('should honor minSize/maxSize when resizing.', () => { fixture.componentInstance.type = SplitterType.Vertical; fixture.detectChanges(); const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; pane1.minSize = '100px'; pane1.maxSize = '300px'; fixture.detectChanges(); const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(100); splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(100); fixture.detectChanges(); expect(pane1.dragSize).toBe('100px'); expect(pane2.dragSize).toBe('300px'); splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(-200); splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(-50); fixture.detectChanges(); expect(pane1.dragSize).toBe('300px'); expect(pane2.dragSize).toBe('100px'); }); it('should not allow drag resize if resizable is set to false.', () => { const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; expect(splitterBarComponent.cursor).toBe('col-resize'); const pane1 = splitter.panes.toArray()[0]; pane1.resizable = false; fixture.detectChanges(); const args = {cancel: false}; splitterBarComponent.onDragStart(args); expect(args.cancel).toBeTruthy(); expect(splitterBarComponent.cursor).toBe(''); }); it('should allow resizing with up/down arrow keys', () => { fixture.componentInstance.type = SplitterType.Vertical; fixture.detectChanges(); const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; expect(pane1.size).toBe('auto'); expect(pane2.size).toBe('auto'); const pane1_originalSize = pane1.element.offsetHeight; const pane2_originalSize = pane2.element.offsetHeight; const splitterBarComponent: DebugElement = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)); splitterBarComponent.nativeElement.focus(); UIInteractions.triggerEventHandlerKeyDown('ArrowUp', splitterBarComponent); fixture.detectChanges(); expect(pane1.dragSize).toBe(pane1_originalSize - 10 + 'px'); expect(pane2.dragSize).toBe(pane2_originalSize + 10 + 'px'); UIInteractions.triggerEventHandlerKeyDown('ArrowDown', splitterBarComponent); UIInteractions.triggerEventHandlerKeyDown('ArrowDown', splitterBarComponent); fixture.detectChanges(); expect(pane1.dragSize).toBe(pane1_originalSize + 10 + 'px'); expect(pane2.dragSize).toBe(pane2_originalSize - 10 + 'px'); pane2.resizable = false; UIInteractions.triggerEventHandlerKeyDown('ArrowDown', splitterBarComponent); fixture.detectChanges(); expect(pane1.dragSize).toBe(pane1_originalSize + 10 + 'px'); expect(pane2.dragSize).toBe(pane2_originalSize - 10 + 'px'); }); it('should allow resizing with left/right arrow keys', () => { fixture.componentInstance.type = SplitterType.Horizontal; fixture.detectChanges(); const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; expect(pane1.size).toBe('auto'); expect(pane2.size).toBe('auto'); const pane1_originalSize = pane1.element.offsetWidth; const pane2_originalSize = pane2.element.offsetWidth; const splitterBarComponent: DebugElement = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)); splitterBarComponent.nativeElement.focus(); UIInteractions.triggerEventHandlerKeyDown('ArrowLeft', splitterBarComponent); fixture.detectChanges(); expect(parseFloat(pane1.dragSize)).toBeCloseTo(pane1_originalSize - 10, 0); expect(parseFloat(pane2.dragSize)).toBeCloseTo(pane2_originalSize + 10, 0); UIInteractions.triggerEventHandlerKeyDown('ArrowRight', splitterBarComponent); UIInteractions.triggerEventHandlerKeyDown('ArrowRight', splitterBarComponent); fixture.detectChanges(); expect(parseFloat(pane1.dragSize)).toBeCloseTo(pane1_originalSize + 10, 0); expect(parseFloat(pane2.dragSize)).toBeCloseTo(pane2_originalSize - 10, 0); pane1.resizable = false; UIInteractions.triggerEventHandlerKeyDown('ArrowRight', splitterBarComponent); fixture.detectChanges(); expect(parseFloat(pane1.dragSize)).toBeCloseTo(pane1_originalSize + 10, 0); expect(parseFloat(pane2.dragSize)).toBeCloseTo(pane2_originalSize - 10, 0); }); it('should allow expand/collapse with Ctrl + up/down arrow keys', () => { fixture.componentInstance.type = SplitterType.Vertical; fixture.detectChanges(); const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; expect(pane1.size).toBe('auto'); expect(pane2.size).toBe('auto'); const splitterBarComponent: DebugElement = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)); splitterBarComponent.nativeElement.focus(); UIInteractions.triggerEventHandlerKeyDown('ArrowUp', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane1.collapsed).toBeTruthy(); UIInteractions.triggerEventHandlerKeyDown('ArrowDown', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane1.collapsed).toBeFalsy(); UIInteractions.triggerEventHandlerKeyDown('ArrowDown', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane2.collapsed).toBeTruthy(); UIInteractions.triggerEventHandlerKeyDown('ArrowUp', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane2.collapsed).toBeFalsy(); }); it('should allow expand/collapse with Ctrl + left/right arrow keys', () => { fixture.componentInstance.type = SplitterType.Horizontal; fixture.detectChanges(); const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; expect(pane1.size).toBe('auto'); expect(pane2.size).toBe('auto'); const splitterBarComponent: DebugElement = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)); splitterBarComponent.nativeElement.focus(); UIInteractions.triggerEventHandlerKeyDown('ArrowLeft', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane1.collapsed).toBeTruthy(); UIInteractions.triggerEventHandlerKeyDown('ArrowRight', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane1.collapsed).toBeFalsy(); UIInteractions.triggerEventHandlerKeyDown('ArrowRight', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane2.collapsed).toBeTruthy(); UIInteractions.triggerEventHandlerKeyDown('ArrowLeft', splitterBarComponent, false, false, true); fixture.detectChanges(); expect(pane2.collapsed).toBeFalsy(); }); it('should allow resize in % when pane size is auto.', () => { const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; expect(pane1.size).toBe('auto'); expect(pane2.size).toBe('auto'); const pane1_originalSize = pane1.element.offsetWidth; const pane2_originalSize = pane2.element.offsetWidth; const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(-100); fixture.detectChanges(); expect(parseFloat(pane1.dragSize)).toBeCloseTo(pane1_originalSize + 100, 0); expect(parseFloat(pane2.dragSize)).toBeCloseTo(pane2_originalSize - 100, 0); // on move end convert to % value and apply to size. splitterBarComponent.movingEnd.emit(-100); fixture.detectChanges(); expect(pane1.size.indexOf('%') !== -1).toBeTrue(); expect(pane2.size.indexOf('%') !== -1).toBeTrue(); expect(pane1.element.offsetWidth).toBeCloseTo(pane1_originalSize + 100); expect(pane2.element.offsetWidth).toBeCloseTo(pane2_originalSize - 100); }); it('should allow mixing % and px sizes.', () => { const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; pane1.size = '200px'; fixture.detectChanges(); const pane1_originalSize = pane1.element.offsetWidth; const pane2_originalSize = pane2.element.offsetWidth; const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; splitterBarComponent.moveStart.emit(pane1); splitterBarComponent.moving.emit(-100); fixture.detectChanges(); expect(parseFloat(pane1.dragSize)).toBeCloseTo(pane1_originalSize + 100, 0); expect(parseFloat(pane2.dragSize)).toBeCloseTo(pane2_originalSize - 100, 0); // on move end convert to % value and apply to size. splitterBarComponent.movingEnd.emit(-100); fixture.detectChanges(); // fist pane should remain in px expect(pane1.size).toBe('300px'); expect(pane2.size.indexOf('%') !== -1).toBeTrue(); expect(pane1.element.offsetWidth).toBeCloseTo(pane1_originalSize + 100); expect(pane2.element.offsetWidth).toBeCloseTo(pane2_originalSize - 100); }); }); describe('IgxSplitter pane toggle', () => { configureTestSuite(); beforeAll(waitForAsync(() => TestBed.configureTestingModule({ imports: [ SplitterTogglePaneComponent ] }).compileComponents())); let fixture; let splitter; beforeEach(waitForAsync(() => { fixture = TestBed.createComponent(SplitterTogglePaneComponent); fixture.detectChanges(); splitter = fixture.componentInstance.splitter; })); it('should collapse/expand panes', () => { const pane1 = splitter.panes.toArray()[0]; const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; // collapse left sibling pane splitterBarComponent.onCollapsing(0); fixture.detectChanges(); expect(pane1.collapsed).toBeTruthy(); // expand left sibling pane splitterBarComponent.onCollapsing(1); fixture.detectChanges(); expect(pane1.collapsed).toBeFalsy(); }); it('should be able to expand both siblings when they are collapsed', () => { const panes = splitter.panes.toArray(); const pane1 = panes[0]; const pane2 = panes[1]; const splitterBarComponents = fixture.debugElement.queryAll(By.css(SPLITTERBAR_CLASS)); const splitterBar1 = splitterBarComponents[0].context; const splitterBar2 = splitterBarComponents[1].context; splitterBar1.onCollapsing(0); splitterBar2.onCollapsing(0); fixture.detectChanges(); expect(pane1.collapsed).toBeTruthy(); expect(pane2.collapsed).toBeTruthy(); splitterBar1.onCollapsing(1); fixture.detectChanges(); expect(pane1.collapsed).toBeFalsy(); }); it('should not be able to resize a pane when it is collapsed', () => { const pane1 = splitter.panes.toArray()[0]; const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; pane1.size = '340'; const pane1_originalSize = pane1.size; const splitterBarComponentDebug: DebugElement = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)); // collapse left sibling pane splitterBarComponent.onCollapsing(0); fixture.detectChanges(); expect(pane1.collapsed).toBeTruthy(); expect(pane1.resizable).toBeTruthy(); splitterBarComponentDebug.nativeElement.focus(); UIInteractions.triggerEventHandlerKeyDown('ArrowRight', splitterBarComponentDebug); fixture.detectChanges(); expect(pane1.size).toEqual(pane1_originalSize); splitterBarComponent.onCollapsing(1); fixture.detectChanges(); expect(pane1.collapsed).toBeFalsy(); expect(pane1.resizable).toBeTruthy(); }); it('should emit resizing events on splitter bar move: resizeStart, resizing, resizeEnd.', () => { fixture.componentInstance.type = SplitterType.Vertical; fixture.detectChanges(); spyOn(splitter.resizeStart, 'emit').and.callThrough(); spyOn(splitter.resizing, 'emit').and.callThrough(); spyOn(splitter.resizeEnd, 'emit').and.callThrough(); const pane1 = splitter.panes.toArray()[0]; const pane2 = splitter.panes.toArray()[1]; const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; splitterBarComponent.moveStart.emit(pane1); fixture.detectChanges(); splitterBarComponent.moving.emit(-100); fixture.detectChanges(); splitterBarComponent.movingEnd.emit(-100); fixture.detectChanges(); const args: ISplitterBarResizeEventArgs = { pane: pane1, sibling: pane2 }; expect(splitter.resizeStart.emit).toHaveBeenCalledTimes(1); expect(splitter.resizeStart.emit).toHaveBeenCalledWith(args); expect(splitter.resizing.emit).toHaveBeenCalledTimes(1); expect(splitter.resizing.emit).toHaveBeenCalledWith(args); expect(splitter.resizeEnd.emit).toHaveBeenCalledTimes(1); expect(splitter.resizeEnd.emit).toHaveBeenCalledWith(args); }); }); describe('IgxSplitter pane collapse', () => { configureTestSuite(); beforeAll(waitForAsync(() => TestBed.configureTestingModule({ imports: [ SplitterCollapsedPaneComponent ] }).compileComponents())); let fixture; let splitter; beforeEach(waitForAsync(() => { fixture = TestBed.createComponent(SplitterCollapsedPaneComponent); fixture.detectChanges(); splitter = fixture.componentInstance.splitter; })); it('should reset sizes when pane is initially collapsed.', () => { const panes = splitter.panes.toArray(); panes.forEach(pane => { expect(pane.size).toBe('auto'); }); }); it('should reset sizes when pane is runtime collapsed.', () => { const panes = splitter.panes.toArray(); panes[0].size = '70%'; fixture.detectChanges(); panes[1].collapsed = true; fixture.detectChanges(); panes.forEach(pane => { expect(pane.size).toBe('auto'); }); }); }); @Component({ template: ` <igx-splitter [type]="type"> <igx-splitter-pane> <div style='height:200px;'> Pane 1 </div> </igx-splitter-pane> <igx-splitter-pane> <div style='height:200px;'> Pane 2 </div> </igx-splitter-pane> </igx-splitter> `, standalone: true, imports: [IgxSplitterComponent, IgxSplitterPaneComponent] }) export class SplitterTestComponent { @ViewChild(IgxSplitterComponent, { static: true }) public splitter: IgxSplitterComponent; public type = SplitterType.Horizontal; } @Component({ template: ` <igx-splitter [type]="type"> <igx-splitter-pane> <div style='height:200px;'> Pane 1 </div> </igx-splitter-pane> <igx-splitter-pane> <div style='height:200px;'> Pane 2 </div> </igx-splitter-pane> <igx-splitter-pane> <div style='height:200px;'> Pane 3 </div> </igx-splitter-pane> </igx-splitter> `, standalone: true, imports: [IgxSplitterComponent, IgxSplitterPaneComponent] }) export class SplitterTogglePaneComponent extends SplitterTestComponent { } @Component({ template: ` <igx-splitter [type]="type"> <igx-splitter-pane size='30%'> <div> Pane 1 </div> </igx-splitter-pane> <igx-splitter-pane size='30%'> <div> Pane 2 </div> </igx-splitter-pane> <igx-splitter-pane size='30%' [collapsed]='true'> <div> Pane 3 </div> </igx-splitter-pane> </igx-splitter> `, standalone: true, imports: [IgxSplitterComponent, IgxSplitterPaneComponent] }) export class SplitterCollapsedPaneComponent extends SplitterTestComponent { }