Skip to content

Commit 4bef998

Browse files
authored
add some basic tests (#11295)
1 parent c196eec commit 4bef998

File tree

2 files changed

+103
-19
lines changed

2 files changed

+103
-19
lines changed

src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ import {CdkVirtualScrollViewport} from './virtual-scroll-viewport';
1010

1111
describe('CdkVirtualScrollViewport', () => {
1212
describe ('with FixedSizeVirtualScrollStrategy', () => {
13-
let fixture: ComponentFixture<FixedVirtualScroll>;
14-
let testComponent: FixedVirtualScroll;
13+
let fixture: ComponentFixture<FixedSizeVirtualScroll>;
14+
let testComponent: FixedSizeVirtualScroll;
1515
let viewport: CdkVirtualScrollViewport;
1616

1717
beforeEach(() => {
1818
TestBed.configureTestingModule({
1919
imports: [ScrollingModule],
20-
declarations: [FixedVirtualScroll],
20+
declarations: [FixedSizeVirtualScroll],
2121
}).compileComponents();
2222

23-
fixture = TestBed.createComponent(FixedVirtualScroll);
23+
fixture = TestBed.createComponent(FixedSizeVirtualScroll);
2424
testComponent = fixture.componentInstance;
2525
viewport = testComponent.viewport;
2626
});
@@ -454,6 +454,45 @@ describe('CdkVirtualScrollViewport', () => {
454454
expect(testComponent.virtualForViewContainer.createEmbeddedView).toHaveBeenCalledTimes(5);
455455
}));
456456
});
457+
458+
describe ('with AutoSizeVirtualScrollStrategy', () => {
459+
let fixture: ComponentFixture<AutoSizeVirtualScroll>;
460+
let testComponent: AutoSizeVirtualScroll;
461+
let viewport: CdkVirtualScrollViewport;
462+
463+
beforeEach(() => {
464+
TestBed.configureTestingModule({
465+
imports: [ScrollingModule],
466+
declarations: [AutoSizeVirtualScroll],
467+
}).compileComponents();
468+
469+
fixture = TestBed.createComponent(AutoSizeVirtualScroll);
470+
testComponent = fixture.componentInstance;
471+
viewport = testComponent.viewport;
472+
});
473+
474+
it('should render initial state for uniform items', fakeAsync(() => {
475+
finishInit(fixture);
476+
477+
const contentWrapper =
478+
viewport.elementRef.nativeElement.querySelector('.cdk-virtual-scroll-content-wrapper');
479+
expect(contentWrapper.children.length)
480+
.toBe(4, 'should render 4 50px items to fill 200px space');
481+
}));
482+
483+
it('should render extra content if first item is smaller than average', fakeAsync(() => {
484+
testComponent.items = [50, 200, 200, 200, 200, 200];
485+
finishInit(fixture);
486+
487+
const contentWrapper =
488+
viewport.elementRef.nativeElement.querySelector('.cdk-virtual-scroll-content-wrapper');
489+
expect(contentWrapper.children.length).toBe(4,
490+
'should render 4 items to fill 200px space based on 50px estimate from first item');
491+
}));
492+
493+
// TODO(mmalerba): Add test that it corrects the initial render if it didn't render enough,
494+
// once it actually does that.
495+
});
457496
});
458497

459498

@@ -506,7 +545,7 @@ function triggerScroll(viewport: CdkVirtualScrollViewport, offset?: number) {
506545
`],
507546
encapsulation: ViewEncapsulation.None,
508547
})
509-
class FixedVirtualScroll {
548+
class FixedSizeVirtualScroll {
510549
@ViewChild(CdkVirtualScrollViewport) viewport: CdkVirtualScrollViewport;
511550
@ViewChild(CdkVirtualForOf, {read: ViewContainerRef}) virtualForViewContainer: ViewContainerRef;
512551

@@ -527,3 +566,46 @@ class FixedVirtualScroll {
527566
return this.orientation == 'horizontal' ? this.viewportCrossSize : this.viewportSize;
528567
}
529568
}
569+
570+
@Component({
571+
template: `
572+
<cdk-virtual-scroll-viewport
573+
autosize [minBufferPx]="minBufferSize" [addBufferPx]="addBufferSize"
574+
[orientation]="orientation" [style.height.px]="viewportHeight"
575+
[style.width.px]="viewportWidth">
576+
<div class="item" *cdkVirtualFor="let size of items; let i = index" [style.height.px]="size"
577+
[style.width.px]="size">
578+
{{i}} - {{size}}
579+
</div>
580+
</cdk-virtual-scroll-viewport>
581+
`,
582+
styles: [`
583+
.cdk-virtual-scroll-content-wrapper {
584+
display: flex;
585+
flex-direction: column;
586+
}
587+
588+
.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper {
589+
flex-direction: row;
590+
}
591+
`],
592+
encapsulation: ViewEncapsulation.None,
593+
})
594+
class AutoSizeVirtualScroll {
595+
@ViewChild(CdkVirtualScrollViewport) viewport: CdkVirtualScrollViewport;
596+
597+
@Input() orientation = 'vertical';
598+
@Input() viewportSize = 200;
599+
@Input() viewportCrossSize = 100;
600+
@Input() minBufferSize = 0;
601+
@Input() addBufferSize = 0;
602+
@Input() items = Array(10).fill(50);
603+
604+
get viewportWidth() {
605+
return this.orientation == 'horizontal' ? this.viewportSize : this.viewportCrossSize;
606+
}
607+
608+
get viewportHeight() {
609+
return this.orientation == 'horizontal' ? this.viewportCrossSize : this.viewportSize;
610+
}
611+
}

src/cdk-experimental/scrolling/virtual-scroll-viewport.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ export class CdkVirtualScrollViewport implements DoCheck, OnInit, OnDestroy {
9999
*/
100100
private _renderedContentOffsetNeedsRewrite = false;
101101

102+
/** Observable that emits when the viewport is destroyed. */
103+
private _destroyed = new Subject<void>();
104+
102105
constructor(public elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef,
103106
private _ngZone: NgZone, private _sanitizer: DomSanitizer,
104107
@Inject(VIRTUAL_SCROLL_STRATEGY) private _scrollStrategy: VirtualScrollStrategy) {}
@@ -114,7 +117,7 @@ export class CdkVirtualScrollViewport implements DoCheck, OnInit, OnDestroy {
114117
fromEvent(viewportEl, 'scroll')
115118
// Sample the scroll stream at every animation frame. This way if there are multiple
116119
// scroll events in the same frame we only need to recheck our layout once.
117-
.pipe(sampleTime(0, animationFrameScheduler))
120+
.pipe(sampleTime(0, animationFrameScheduler), takeUntil(this._destroyed))
118121
.subscribe(() => this._scrollStrategy.onContentScrolled());
119122
});
120123
});
@@ -135,10 +138,12 @@ export class CdkVirtualScrollViewport implements DoCheck, OnInit, OnDestroy {
135138
ngOnDestroy() {
136139
this.detach();
137140
this._scrollStrategy.detach();
141+
this._destroyed.next();
138142

139143
// Complete all subjects
140144
this._renderedRangeSubject.complete();
141145
this._detachedSubject.complete();
146+
this._destroyed.complete();
142147
}
143148

144149
/** Attaches a `CdkVirtualForOf` to this viewport. */
@@ -208,20 +213,17 @@ export class CdkVirtualScrollViewport implements DoCheck, OnInit, OnDestroy {
208213
this._ngZone.run(() => {
209214
this._renderedRangeSubject.next(this._renderedRange = range);
210215
this._changeDetectorRef.markForCheck();
211-
this._ngZone.runOutsideAngular(() => this._ngZone.onStable.pipe(take(1)).subscribe(() => {
212-
// Queue this up in a `Promise.resolve()` so that if the user makes a series of calls
213-
// like:
214-
//
215-
// viewport.setRenderedRange(...);
216-
// viewport.setTotalContentSize(...);
217-
// viewport.setRenderedContentOffset(...);
218-
//
219-
// The call to `onContentRendered` will happen after all of the updates have been applied.
220-
Promise.resolve().then(() => {
221-
this._scrollStrategy.onContentRendered();
222-
});
223-
}));
224216
});
217+
// Queue this up in a `Promise.resolve()` so that if the user makes a series of calls
218+
// like:
219+
//
220+
// viewport.setRenderedRange(...);
221+
// viewport.setTotalContentSize(...);
222+
// viewport.setRenderedContentOffset(...);
223+
//
224+
// The call to `onContentRendered` will happen after all of the updates have been applied.
225+
this._ngZone.runOutsideAngular(() => this._ngZone.onStable.pipe(take(1)).subscribe(
226+
() => Promise.resolve().then(() => this._scrollStrategy.onContentRendered())));
225227
}
226228
}
227229

0 commit comments

Comments
 (0)