@@ -8,13 +8,21 @@ import {
88 dispatchEvent ,
99} from '@angular/cdk/testing/private' ;
1010import { ESCAPE , A } from '@angular/cdk/keycodes' ;
11- import { Overlay , CdkConnectedOverlay , OverlayModule , CdkOverlayOrigin } from './index' ;
11+ import {
12+ Overlay ,
13+ CdkConnectedOverlay ,
14+ OverlayModule ,
15+ CdkOverlayOrigin ,
16+ ScrollDispatcher ,
17+ ScrollStrategy ,
18+ } from './index' ;
1219import { OverlayContainer } from './overlay-container' ;
1320import {
1421 ConnectedOverlayPositionChange ,
1522 ConnectionPositionPair ,
1623} from './position/connected-position' ;
1724import { FlexibleConnectedPositionStrategy } from './position/flexible-connected-position-strategy' ;
25+ import { Subject } from 'rxjs' ;
1826
1927
2028describe ( 'Overlay directives' , ( ) => {
@@ -23,12 +31,17 @@ describe('Overlay directives', () => {
2331 let overlayContainerElement : HTMLElement ;
2432 let fixture : ComponentFixture < ConnectedOverlayDirectiveTest > ;
2533 let dir : { value : string } ;
34+ let scrolledSubject = new Subject ( ) ;
2635
2736 beforeEach ( ( ) => {
2837 TestBed . configureTestingModule ( {
2938 imports : [ OverlayModule ] ,
3039 declarations : [ ConnectedOverlayDirectiveTest , ConnectedOverlayPropertyInitOrder ] ,
31- providers : [ { provide : Directionality , useFactory : ( ) => dir = { value : 'ltr' } } ] ,
40+ providers : [ { provide : Directionality , useFactory : ( ) => dir = { value : 'ltr' } } ,
41+ { provide : ScrollDispatcher , useFactory : ( ) => ( {
42+ scrolled : ( ) => scrolledSubject . asObservable ( )
43+ } ) }
44+ ] ,
3245 } ) ;
3346 } ) ;
3447
@@ -529,7 +542,7 @@ describe('Overlay directives', () => {
529542 } ) ;
530543
531544 describe ( 'outputs' , ( ) => {
532- it ( 'should emit backdropClick appropriately ' , ( ) => {
545+ it ( 'should emit when the backdrop was clicked ' , ( ) => {
533546 fixture . componentInstance . hasBackdrop = true ;
534547 fixture . componentInstance . isOpen = true ;
535548 fixture . detectChanges ( ) ;
@@ -543,7 +556,7 @@ describe('Overlay directives', () => {
543556 . toHaveBeenCalledWith ( jasmine . any ( MouseEvent ) ) ;
544557 } ) ;
545558
546- it ( 'should emit positionChange appropriately ' , ( ) => {
559+ it ( 'should emit when the position has changed ' , ( ) => {
547560 expect ( fixture . componentInstance . positionChangeHandler ) . not . toHaveBeenCalled ( ) ;
548561 fixture . componentInstance . isOpen = true ;
549562 fixture . detectChanges ( ) ;
@@ -556,15 +569,24 @@ describe('Overlay directives', () => {
556569 . toBe ( true , `Expected directive to emit an instance of ConnectedOverlayPositionChange.` ) ;
557570 } ) ;
558571
559- it ( 'should emit attach and detach appropriately ' , ( ) => {
572+ it ( 'should emit when attached ' , ( ) => {
560573 expect ( fixture . componentInstance . attachHandler ) . not . toHaveBeenCalled ( ) ;
561- expect ( fixture . componentInstance . detachHandler ) . not . toHaveBeenCalled ( ) ;
562574 fixture . componentInstance . isOpen = true ;
563575 fixture . detectChanges ( ) ;
564576
565577 expect ( fixture . componentInstance . attachHandler ) . toHaveBeenCalled ( ) ;
566578 expect ( fixture . componentInstance . attachResult instanceof HTMLElement )
567579 . toBe ( true , `Expected pane to be populated with HTML elements when attach was called.` ) ;
580+
581+ fixture . componentInstance . isOpen = false ;
582+ fixture . detectChanges ( ) ;
583+ } ) ;
584+
585+ it ( 'should emit when detached' , ( ) => {
586+ expect ( fixture . componentInstance . detachHandler ) . not . toHaveBeenCalled ( ) ;
587+ fixture . componentInstance . isOpen = true ;
588+ fixture . detectChanges ( ) ;
589+
568590 expect ( fixture . componentInstance . detachHandler ) . not . toHaveBeenCalled ( ) ;
569591
570592 fixture . componentInstance . isOpen = false ;
@@ -584,11 +606,40 @@ describe('Overlay directives', () => {
584606 expect ( fixture . componentInstance . keydownHandler ) . toHaveBeenCalledWith ( event ) ;
585607 } ) ;
586608
609+ it ( 'should emit when detached externally' , ( ) => {
610+ expect ( fixture . componentInstance . detachHandler ) . not . toHaveBeenCalled ( ) ;
611+ fixture . componentInstance . scrollStrategy = overlay . scrollStrategies . close ( ) ;
612+ fixture . componentInstance . isOpen = true ;
613+ fixture . detectChanges ( ) ;
614+
615+ expect ( fixture . componentInstance . detachHandler ) . not . toHaveBeenCalled ( ) ;
616+
617+ scrolledSubject . next ( ) ;
618+ fixture . detectChanges ( ) ;
619+
620+ expect ( fixture . componentInstance . detachHandler ) . toHaveBeenCalled ( ) ;
621+ } ) ;
622+
623+ // This is intended as a simplified example of a more complicated bug in g3. Technically
624+ // these events shouldn't invoke their listeners after destruction anyway, but in some
625+ // tests it can happen. For more context: https://github.com/crisbeto/material2/pull/10
626+ it ( 'should not emit after the directive is destroyed' , ( ) => {
627+ const spy = jasmine . createSpy ( 'detach spy' ) ;
628+ const subscription =
629+ fixture . componentInstance . connectedOverlayDirective . detach . subscribe ( spy ) ;
630+
631+ fixture . componentInstance . isOpen = true ;
632+ fixture . detectChanges ( ) ;
633+ fixture . destroy ( ) ;
634+
635+ expect ( spy ) . not . toHaveBeenCalled ( ) ;
636+ subscription . unsubscribe ( ) ;
637+ } ) ;
638+
587639 } ) ;
588640
589641} ) ;
590642
591-
592643@Component ( {
593644 template : `
594645 <button cdk-overlay-origin id="trigger" #trigger="cdkOverlayOrigin">Toggle menu</button>
@@ -605,6 +656,7 @@ describe('Overlay directives', () => {
605656 [cdkConnectedOverlayFlexibleDimensions]="flexibleDimensions"
606657 [cdkConnectedOverlayGrowAfterOpen]="growAfterOpen"
607658 [cdkConnectedOverlayPush]="push"
659+ [cdkConnectedOverlayScrollStrategy]="scrollStrategy"
608660 cdkConnectedOverlayBackdropClass="mat-test-class"
609661 cdkConnectedOverlayPanelClass="cdk-test-panel-class"
610662 (backdropClick)="backdropClickHandler($event)"
@@ -640,13 +692,14 @@ class ConnectedOverlayDirectiveTest {
640692 flexibleDimensions : boolean ;
641693 growAfterOpen : boolean ;
642694 push : boolean ;
695+ scrollStrategy : ScrollStrategy ;
643696 backdropClickHandler = jasmine . createSpy ( 'backdropClick handler' ) ;
644697 positionChangeHandler = jasmine . createSpy ( 'positionChange handler' ) ;
645698 keydownHandler = jasmine . createSpy ( 'keydown handler' ) ;
646699 positionOverrides : ConnectionPositionPair [ ] ;
647700 attachHandler = jasmine . createSpy ( 'attachHandler' ) . and . callFake ( ( ) => {
648- this . attachResult =
649- this . connectedOverlayDirective . overlayRef . overlayElement . querySelector ( 'p' ) as HTMLElement ;
701+ const overlayElement = this . connectedOverlayDirective . overlayRef . overlayElement ;
702+ this . attachResult = overlayElement . querySelector ( 'p' ) as HTMLElement ;
650703 } ) ;
651704 detachHandler = jasmine . createSpy ( 'detachHandler' ) ;
652705 attachResult : HTMLElement ;
0 commit comments