Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
varnastadeus committed Jun 15, 2019
1 parent 5d5344a commit 7298106
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 107 deletions.
39 changes: 22 additions & 17 deletions src/ng-select/ng-dropdown-panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { auditTime, takeUntil } from 'rxjs/operators';
import { DropdownPosition } from './ng-select.component';
import { NgOption } from './ng-select.types';
import { isDefined } from './value-utils';
import { PanelDimensions, VirtualScrollService } from './virtual-scroll.service';
import { PanelDimensions, NgDropdownPanelService } from './ng-dropdown-panel.service';

const TOP_CSS_CLASS = 'ng-select-top';
const BOTTOM_CSS_CLASS = 'ng-select-bottom';
Expand Down Expand Up @@ -85,7 +85,7 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
constructor(
private _renderer: Renderer2,
private _zone: NgZone,
private _virtualScrollService: VirtualScrollService,
private _panelService: NgDropdownPanelService,
_elementRef: ElementRef,
@Optional() @Inject(DOCUMENT) private _document: any
) {
Expand Down Expand Up @@ -146,7 +146,7 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
}
}

scrollTo(option: NgOption) {
scrollTo(option: NgOption, startFromOption = false) {
if (!option) {
return;
}
Expand All @@ -158,11 +158,12 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {

let scrollTo;
if (this.virtualScroll) {
const itemHeight = this._virtualScrollService.dimensions.itemHeight;
scrollTo = this._virtualScrollService.getScrollTo(index * itemHeight, itemHeight, this._lastScrollPosition);
const itemHeight = this._panelService.dimensions.itemHeight;
scrollTo = this._panelService.getScrollTo(index * itemHeight, itemHeight, this._lastScrollPosition);
} else {
const item: HTMLElement = this._dropdown.querySelector(`#${option.htmlId}`);
scrollTo = this._virtualScrollService.getScrollTo(item.offsetTop, item.clientHeight, this._lastScrollPosition);
const lastScroll = startFromOption ? item.offsetTop : this._lastScrollPosition;
scrollTo = this._panelService.getScrollTo(item.offsetTop, item.clientHeight, lastScroll);
}

if (isDefined(scrollTo)) {
Expand All @@ -173,7 +174,7 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
scrollToTag() {
// TODO: needs fix ?
const el: Element = this.scrollElementRef.nativeElement;
const d = this._virtualScrollService.dimensions;
const d = this._panelService.dimensions;
el.scrollTop = d.itemHeight * (this.itemsLength + 1);
}

Expand Down Expand Up @@ -251,19 +252,23 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
if (this.virtualScroll) {
this._updateItemsRange(firstChange);
} else {
this._updateItems();
this._updateItems(firstChange);
}
}

private _updateItems() {
private _updateItems(firstChange: boolean) {
this.update.emit(this.items);

if (firstChange === false) {
return;
}

this._zone.runOutsideAngular(() => {
Promise.resolve().then(() => {
const panelHeight = this._scrollablePanel.clientHeight;
this._virtualScrollService.setDimensions(0, panelHeight);
this._handleDropdownPosition(); // TODO: only on first change?
this.scrollTo(this.markedItem);
this._panelService.setDimensions(0, panelHeight);
this._handleDropdownPosition();
this.scrollTo(this.markedItem, firstChange);
});
});
}
Expand Down Expand Up @@ -309,7 +314,7 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
}

scrollTop = scrollTop || this._scrollablePanel.scrollTop;
const range = this._virtualScrollService.calculateItems(scrollTop, this.itemsLength, this.bufferAmount);
const range = this._panelService.calculateItems(scrollTop, this.itemsLength, this.bufferAmount);
this._updateVirtualHeight(range.scrollHeight);
this._contentPanel.style.transform = 'translateY(' + range.topPadding + 'px)';

Expand All @@ -325,8 +330,8 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
}

private _measureDimensions(): Promise<PanelDimensions> {
if (this._virtualScrollService.dimensions) {
return Promise.resolve(this._virtualScrollService.dimensions);
if (this._panelService.dimensions) {
return Promise.resolve(this._panelService.dimensions);
}

return new Promise(resolve => {
Expand All @@ -337,9 +342,9 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
const optionHeight = option.clientHeight;
this._virtualPadding.style.height = `${optionHeight * this.itemsLength}px`;
const panelHeight = this._scrollablePanel.clientHeight;
this._virtualScrollService.setDimensions(optionHeight, panelHeight);
this._panelService.setDimensions(optionHeight, panelHeight);

resolve(this._virtualScrollService.dimensions);
resolve(this._panelService.dimensions);
});
});
}
Expand Down
71 changes: 71 additions & 0 deletions src/ng-select/ng-dropdown-panel.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { TestBed } from '@angular/core/testing';
import { NgDropdownPanelService } from './ng-dropdown-panel.service';

describe('NgDropdownPanelService', () => {

let service: NgDropdownPanelService;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [NgDropdownPanelService]
});

service = TestBed.get(NgDropdownPanelService);
});

describe('calculate items', () => {
it('should calculate items from start', () => {
const itemsLength = 100;
const buffer = 4;

service.setDimensions(25, 100);
const res = service.calculateItems(0, itemsLength, buffer);

expect(res).toEqual({
start: 0,
end: 9,
topPadding: 0,
scrollHeight: 2500
})
});

it('should calculate items when scrolled', () => {
const itemsLength = 100;
const buffer = 4;

service.setDimensions(25, 100);
const res = service.calculateItems(1250, itemsLength, buffer);

expect(res).toEqual({
start: 46,
end: 59,
topPadding: 1150,
scrollHeight: 2500
})
});
});

describe('scroll to', () => {
beforeEach(() => {
service.setDimensions(40, 240);
});

it('should not scroll if item is in visible area', () => {
expect(service.getScrollTo(0, 40, 0)).toBe(0);
expect(service.getScrollTo(200, 40, 0)).toBeNull();
});

it('should scroll by item height', () => {
expect(service.getScrollTo(240, 40, 0)).toBe(40);
});

it('should start from top when reached bottom', () => {
expect(service.getScrollTo(0, 40, 400)).toBe(0);
});

it('should move to bottom when reached top', () => {
expect(service.getScrollTo(600, 40, 0)).toBe(400);
});
});
})
;
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { isDefined } from './value-utils';

export interface ItemsRangeResult {
scrollHeight: number;
topPadding: number;
Expand All @@ -13,7 +11,7 @@ export interface PanelDimensions {
itemsPerViewport: number;
}

export class VirtualScrollService {
export class NgDropdownPanelService {

private _dimensions: PanelDimensions;

Expand Down Expand Up @@ -61,13 +59,15 @@ export class VirtualScrollService {

getScrollTo(itemTop: number, itemHeight: number, lastScroll: number) {
const itemBottom = itemTop + itemHeight;
const top = isDefined(lastScroll) ? lastScroll : itemTop; // TODO: needs fix, lastScroll always defined
const top = lastScroll;
const bottom = top + this.dimensions.panelHeight;

if (itemBottom > bottom) {
return top + itemBottom - bottom;
} else if (itemTop <= top) {
return itemTop;
}

return null;
}
}
16 changes: 5 additions & 11 deletions src/ng-select/ng-select.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { ConsoleService } from './console.service';
import { FormsModule } from '@angular/forms';
import { getNgSelectElement, selectOption, TestsErrorHandler, tickAndDetectChanges, triggerKeyDownEvent } from '../testing/helpers';
import { KeyCode, NgOption } from './ng-select.types';
import { MockConsole, MockNgWindow, MockNgZone } from '../testing/mocks';
import { MockConsole, MockNgZone } from '../testing/mocks';
import { NgSelectComponent } from './ng-select.component';
import { NgSelectModule } from './ng-select.module';
import { Subject } from 'rxjs';
import { WindowService } from './window.service';

describe('NgSelectComponent', () => {

Expand Down Expand Up @@ -984,7 +983,7 @@ describe('NgSelectComponent', () => {
fixture.componentInstance.cities = Array.from(Array(30).keys()).map((_, i) => ({ id: i, name: String.fromCharCode(97 + i) }));
tickAndDetectChanges(fixture);
options = fixture.debugElement.nativeElement.querySelectorAll('.ng-option');
expect(options.length).toBe(6);
expect(options.length).toBe(8);
expect(options[0].innerText).toBe('a');
}));

Expand Down Expand Up @@ -1021,17 +1020,15 @@ describe('NgSelectComponent', () => {
const cmp = fixture.componentInstance;
const el: HTMLElement = fixture.debugElement.nativeElement;

cmp.select.open();
tickAndDetectChanges(fixture);

cmp.cities = Array.from(Array(30).keys()).map((_, i) => ({ id: i, name: String.fromCharCode(97 + i) }));
cmp.select.open();
tickAndDetectChanges(fixture);

cmp.select.dropdownPanel.scrollTo(cmp.select.itemsList.items[15]);
tickAndDetectChanges(fixture);

const panelItems = el.querySelector('.ng-dropdown-panel-items');
expect(panelItems.scrollTop).toBe(270);
expect(panelItems.scrollTop).toBe(48);
}));

it('should close on option select by default', fakeAsync(() => {
Expand Down Expand Up @@ -1117,7 +1114,7 @@ describe('NgSelectComponent', () => {
expect(fixture.componentInstance.select.isOpen).toBeTruthy();
}));

it('should not append dropdown, nor update its position when it is destroyed', async(() => {
it('should remove appended dropdown when it is destroyed', async(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
`
Expand All @@ -1132,8 +1129,6 @@ describe('NgSelectComponent', () => {
fixture.detectChanges();

fixture.whenStable().then(() => {
const selectClasses = (<HTMLElement>fixture.nativeElement).querySelector('.ng-select').classList;
expect(selectClasses.contains('ng-select-bottom')).toBeFalsy();
const dropdown = <HTMLElement>document.querySelector('.ng-dropdown-panel');
expect(dropdown).toBeNull();
});
Expand Down Expand Up @@ -3373,7 +3368,6 @@ function createTestingModule<T>(cmp: Type<T>, template: string): ComponentFixtur
providers: [
{ provide: ErrorHandler, useClass: TestsErrorHandler },
{ provide: NgZone, useFactory: () => new MockNgZone() },
{ provide: WindowService, useFactory: () => new MockNgWindow() },
{ provide: ConsoleService, useFactory: () => new MockConsole() }
]
})
Expand Down
4 changes: 2 additions & 2 deletions src/ng-select/ng-select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import { NgDropdownPanelComponent } from './ng-dropdown-panel.component';
import { NgOptionComponent } from './ng-option.component';
import { SelectionModelFactory } from './selection-model';
import { NgSelectConfig } from './config.service';
import { VirtualScrollService } from './virtual-scroll.service';
import { NgDropdownPanelService } from './ng-dropdown-panel.service';

export const SELECTION_MODEL_FACTORY = new InjectionToken<SelectionModelFactory>('ng-select-selection-model');
export type DropdownPosition = 'bottom' | 'top' | 'auto';
Expand All @@ -68,7 +68,7 @@ export type GroupValueFn = (key: string | object, children: any[]) => string | o
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgSelectComponent),
multi: true
}, VirtualScrollService],
}, NgDropdownPanelService],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
Expand Down
48 changes: 0 additions & 48 deletions src/ng-select/virtual-scroll.service.spec.ts

This file was deleted.

12 changes: 0 additions & 12 deletions src/ng-select/window.service.ts

This file was deleted.

13 changes: 0 additions & 13 deletions src/testing/mocks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Injectable, NgZone } from '@angular/core';
import { WindowService } from '../ng-select/window.service';

@Injectable()
export class MockNgZone extends NgZone {
Expand All @@ -16,18 +15,6 @@ export class MockNgZone extends NgZone {
}
}

@Injectable()
export class MockNgWindow extends WindowService {
requestAnimationFrame(fn: Function): any {
return fn();
}

setTimeout(handler: (...args: any[]) => void, _: number): number {
handler();
return 0;
}
}

@Injectable()
export class MockConsole {
warn() {
Expand Down

0 comments on commit 7298106

Please sign in to comment.