Skip to content

Commit 5888495

Browse files
committed
finish tests
1 parent 981c5d9 commit 5888495

File tree

4 files changed

+40
-20
lines changed

4 files changed

+40
-20
lines changed

src/lib/core/overlay/scroll/scroll-dispatcher.spec.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {inject, TestBed, async, ComponentFixture} from '@angular/core/testing';
2-
import {NgModule, Component, ViewChild, ElementRef, QueryList, ViewChildren} from '@angular/core';
1+
import {inject, TestBed, async, fakeAsync, ComponentFixture, tick} from '@angular/core/testing';
2+
import {NgModule, Component, ViewChild, ElementRef} from '@angular/core';
33
import {ScrollDispatcher} from './scroll-dispatcher';
44
import {OverlayModule} from '../overlay-directives';
55
import {Scrollable} from './scrollable';
@@ -38,15 +38,17 @@ describe('Scroll Dispatcher', () => {
3838
expect(scroll.scrollableReferences.has(componentScrollable)).toBe(false);
3939
});
4040

41-
it('should notify through the directive and service that a scroll event occurred', () => {
41+
it('should notify through the directive and service that a scroll event occurred',
42+
fakeAsync(() => {
4243
let hasDirectiveScrollNotified = false;
4344
// Listen for notifications from scroll directive
4445
let scrollable = fixture.componentInstance.scrollable;
4546
scrollable.elementScrolled().subscribe(() => { hasDirectiveScrollNotified = true; });
4647

47-
// Listen for notifications from scroll service
48+
// Listen for notifications from scroll service with a throttle of 100ms
49+
const throttleTime = 100;
4850
let hasServiceScrollNotified = false;
49-
scroll.scrolled().subscribe(() => { hasServiceScrollNotified = true; });
51+
scroll.scrolled(throttleTime).subscribe(() => { hasServiceScrollNotified = true; });
5052

5153
// Emit a scroll event from the scrolling element in our component.
5254
// This event should be picked up by the scrollable directive and notify.
@@ -55,9 +57,17 @@ describe('Scroll Dispatcher', () => {
5557
scrollEvent.initUIEvent('scroll', true, true, window, 0);
5658
fixture.componentInstance.scrollingElement.nativeElement.dispatchEvent(scrollEvent);
5759

60+
// The scrollable directive should have notified the service immediately.
5861
expect(hasDirectiveScrollNotified).toBe(true);
62+
63+
// Verify that the throttle is used, the service should wait for the throttle time until
64+
// sending the notification.
65+
expect(hasServiceScrollNotified).toBe(false);
66+
67+
// After the throttle time, the notification should be sent.
68+
tick(throttleTime);
5969
expect(hasServiceScrollNotified).toBe(true);
60-
});
70+
}));
6171
});
6272

6373
describe('Nested scrollables', () => {
@@ -107,7 +117,6 @@ class ScrollingComponent {
107117
})
108118
class NestedScrollingComponent {
109119
@ViewChild('interestingElement') interestingElement: ElementRef;
110-
@ViewChildren(Scrollable) scrollables: QueryList<Scrollable>;
111120
}
112121

113122
const TEST_COMPONENTS = [ScrollingComponent, NestedScrollingComponent];

src/lib/core/overlay/scroll/scroll-dispatcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class ScrollDispatcher {
5757
/**
5858
* Returns an observable that emits an event whenever any of the registered Scrollable
5959
* references (or window, document, or body) fire a scrolled event. Can provide a time in ms
60-
* to override the default throttling time.
60+
* to override the default "throttle" time.
6161
*/
6262
scrolled(auditTimeInMs: number = DEFAULT_AUDIT_TIME): Observable<void> {
6363
return this._scrolled.asObservable().auditTime(auditTimeInMs);

src/lib/tooltip/tooltip.spec.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from '@angular/core/testing';
99
import {Component, DebugElement, AnimationTransitionEvent, ViewChild} from '@angular/core';
1010
import {By} from '@angular/platform-browser';
11-
import {TooltipPosition, MdTooltip, MdTooltipModule} from './tooltip';
11+
import {TooltipPosition, MdTooltip, MdTooltipModule, SCROLL_THROTTLE_MS} from './tooltip';
1212
import {OverlayContainer} from '../core';
1313
import {Dir, LayoutDirection} from '../core/rtl/dir';
1414
import {OverlayModule} from '../core/overlay/overlay-directives';
@@ -27,6 +27,7 @@ describe('MdTooltip', () => {
2727
providers: [
2828
{provide: OverlayContainer, useFactory: () => {
2929
overlayContainerElement = document.createElement('div');
30+
document.body.appendChild(overlayContainerElement);
3031
return {getContainerElement: () => overlayContainerElement};
3132
}},
3233
{provide: Dir, useFactory: () => {
@@ -315,12 +316,22 @@ describe('MdTooltip', () => {
315316
it('should hide tooltip if clipped after changing positions', fakeAsync(() => {
316317
expect(tooltipDirective._tooltipInstance).toBeUndefined();
317318

319+
// Show the tooltip and tick for the show delay (default is 0)
318320
tooltipDirective.show();
319-
tick(0); // Tick for the show delay (default is 0)
321+
fixture.detectChanges();
322+
tick(0);
323+
324+
// Expect that the tooltip is displayed
320325
expect(tooltipDirective._isTooltipVisible()).toBe(true);
321326

327+
// Scroll the page but tick just before the default throttle should update.
322328
fixture.componentInstance.scrollDown();
323-
tick();
329+
tick(SCROLL_THROTTLE_MS - 1);
330+
expect(tooltipDirective._isTooltipVisible()).toBe(true);
331+
332+
// Finish ticking to the throttle's limit and check that the scroll event notified the
333+
// tooltip and it was hidden.
334+
tick(1);
324335
expect(tooltipDirective._isTooltipVisible()).toBe(false);
325336
}));
326337
});
@@ -344,7 +355,8 @@ class BasicTooltipDemo {
344355
@Component({
345356
selector: 'app',
346357
template: `
347-
<div cdk-scrollable style="margin-top: 300px; height: 200px; width: 200px; overflow: auto;">
358+
<div cdk-scrollable style="padding: 100px; margin: 300px;
359+
height: 200px; width: 200px; overflow: auto;">
348360
<button *ngIf="showButton" style="margin-bottom: 350px"
349361
[md-tooltip]="message"
350362
[tooltip-position]="position">
@@ -361,7 +373,7 @@ class ScrollableTooltipDemo {
361373

362374
scrollDown() {
363375
const scrollingContainerEl = this.scrollingContainer.getElementRef().nativeElement;
364-
scrollingContainerEl.scrollTop = 50;
376+
scrollingContainerEl.scrollTop = 140;
365377

366378
// Emit a scroll event from the scrolling element in our component.
367379
// This event should be picked up by the scrollable directive and notify.

src/lib/tooltip/tooltip.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ export type TooltipPosition = 'left' | 'right' | 'above' | 'below' | 'before' |
3838
/** Time in ms to delay before changing the tooltip visibility to hidden */
3939
export const TOUCHEND_HIDE_DELAY = 1500;
4040

41+
/** Time in ms to throttle repositioning after scroll events. */
42+
export const SCROLL_THROTTLE_MS = 20;
43+
4144
/**
4245
* Directive that attaches a material design tooltip to the host element. Animates the showing and
4346
* hiding of a tooltip provided position (defaults to below the element).
@@ -112,17 +115,13 @@ export class MdTooltip implements OnInit, OnDestroy {
112115
ngOnInit() {
113116
// When a scroll on the page occurs, update the position in case this tooltip needs
114117
// to be repositioned.
115-
this._scrollDispatcher.scrolled().subscribe(() => {
116-
if (this._scrollDispatcher.events > 1) {
117-
console.log(`Saved ${this._scrollDispatcher.events - 1} ${this._scrollDispatcher.events > 1 ? 'events' : 'event'}`);
118-
}
119-
this._scrollDispatcher.events = 0;
118+
this._scrollDispatcher.scrolled(SCROLL_THROTTLE_MS).subscribe(() => {
120119
if (this._overlayRef) {
121120
this._overlayRef.updatePosition();
122121
}
123122
});
124123
}
125-
124+
126125
/**
127126
* Dispose the tooltip when destroyed.
128127
*/
@@ -187,7 +186,7 @@ export class MdTooltip implements OnInit, OnDestroy {
187186
let strategy = this._overlay.position().connectedTo(this._elementRef, origin, position);
188187
strategy.withScrollableContainers(this._scrollDispatcher.getScrollContainers(this._elementRef));
189188
strategy.onPositionChange.subscribe(change => {
190-
if (change.scrollableViewProperties.isOverlayClipped) {
189+
if (change.scrollableViewProperties.isOverlayClipped && this._tooltipInstance.isVisible()) {
191190
this.hide(0);
192191
}
193192
});

0 commit comments

Comments
 (0)