1- import { Component } from '@angular/core' ;
2- import { async , TestBed , ComponentFixture } from '@angular/core/testing' ;
3- import { MatSidenav , MatSidenavModule } from './index' ;
1+ import { Component , ViewChild } from '@angular/core' ;
2+ import { async , TestBed , fakeAsync , tick } from '@angular/core/testing' ;
3+ import { MatSidenav , MatSidenavModule , MatSidenavContainer } from './index' ;
44import { NoopAnimationsModule } from '@angular/platform-browser/animations' ;
55import { By } from '@angular/platform-browser' ;
6+ import { CommonModule } from '@angular/common' ;
67
78
89describe ( 'MatSidenav' , ( ) => {
9- let fixture : ComponentFixture < SidenavWithFixedPosition > ;
10- let sidenavEl : HTMLElement ;
11-
1210 beforeEach ( async ( ( ) => {
1311 TestBed . configureTestingModule ( {
14- imports : [ MatSidenavModule , NoopAnimationsModule ] ,
15- declarations : [ SidenavWithFixedPosition ] ,
12+ imports : [ MatSidenavModule , NoopAnimationsModule , CommonModule ] ,
13+ declarations : [ SidenavWithFixedPosition , IndirectDescendantSidenav , NestedSidenavContainers ] ,
1614 } ) ;
1715
1816 TestBed . compileComponents ( ) ;
19-
20- fixture = TestBed . createComponent ( SidenavWithFixedPosition ) ;
21- fixture . detectChanges ( ) ;
22-
23- sidenavEl = fixture . debugElement . query ( By . directive ( MatSidenav ) ) ! . nativeElement ;
2417 } ) ) ;
2518
2619 it ( 'should be fixed position when in fixed mode' , ( ) => {
20+ const fixture = TestBed . createComponent ( SidenavWithFixedPosition ) ;
21+ fixture . detectChanges ( ) ;
22+ const sidenavEl = fixture . debugElement . query ( By . directive ( MatSidenav ) ) ! . nativeElement ;
23+
2724 expect ( sidenavEl . classList ) . toContain ( 'mat-sidenav-fixed' ) ;
2825
2926 fixture . componentInstance . fixed = false ;
@@ -33,6 +30,10 @@ describe('MatSidenav', () => {
3330 } ) ;
3431
3532 it ( 'should set fixed bottom and top when in fixed mode' , ( ) => {
33+ const fixture = TestBed . createComponent ( SidenavWithFixedPosition ) ;
34+ fixture . detectChanges ( ) ;
35+ const sidenavEl = fixture . debugElement . query ( By . directive ( MatSidenav ) ) ! . nativeElement ;
36+
3637 expect ( sidenavEl . style . top ) . toBe ( '20px' ) ;
3738 expect ( sidenavEl . style . bottom ) . toBe ( '30px' ) ;
3839
@@ -42,6 +43,46 @@ describe('MatSidenav', () => {
4243 expect ( sidenavEl . style . top ) . toBeFalsy ( ) ;
4344 expect ( sidenavEl . style . bottom ) . toBeFalsy ( ) ;
4445 } ) ;
46+
47+ it ( 'should pick up sidenavs that are not direct descendants' , fakeAsync ( ( ) => {
48+ const fixture = TestBed . createComponent ( IndirectDescendantSidenav ) ;
49+ fixture . detectChanges ( ) ;
50+
51+ expect ( fixture . componentInstance . sidenav . opened ) . toBe ( false ) ;
52+
53+ fixture . componentInstance . container . open ( ) ;
54+ fixture . detectChanges ( ) ;
55+ tick ( ) ;
56+ fixture . detectChanges ( ) ;
57+
58+ expect ( fixture . componentInstance . sidenav . opened ) . toBe ( true ) ;
59+ } ) ) ;
60+
61+ it ( 'should not pick up sidenavs from nested containers' , fakeAsync ( ( ) => {
62+ const fixture = TestBed . createComponent ( NestedSidenavContainers ) ;
63+ const instance = fixture . componentInstance ;
64+ fixture . detectChanges ( ) ;
65+
66+ expect ( instance . outerSidenav . opened ) . toBe ( false ) ;
67+ expect ( instance . innerSidenav . opened ) . toBe ( false ) ;
68+
69+ instance . outerContainer . open ( ) ;
70+ fixture . detectChanges ( ) ;
71+ tick ( ) ;
72+ fixture . detectChanges ( ) ;
73+
74+ expect ( instance . outerSidenav . opened ) . toBe ( true ) ;
75+ expect ( instance . innerSidenav . opened ) . toBe ( false ) ;
76+
77+ instance . innerContainer . open ( ) ;
78+ fixture . detectChanges ( ) ;
79+ tick ( ) ;
80+ fixture . detectChanges ( ) ;
81+
82+ expect ( instance . outerSidenav . opened ) . toBe ( true ) ;
83+ expect ( instance . innerSidenav . opened ) . toBe ( true ) ;
84+ } ) ) ;
85+
4586} ) ;
4687
4788
@@ -65,3 +106,39 @@ class SidenavWithFixedPosition {
65106 fixedTop = 20 ;
66107 fixedBottom = 30 ;
67108}
109+
110+
111+ @Component ( {
112+ // Note that we need the `ng-container` with the `ngSwitch` so that
113+ // there's a directive between the container and the sidenav.
114+ template : `
115+ <mat-sidenav-container #container>
116+ <ng-container [ngSwitch]="true">
117+ <mat-sidenav #sidenav>Sidenav.</mat-sidenav>
118+ </ng-container>
119+ <mat-sidenav-content>Some content.</mat-sidenav-content>
120+ </mat-sidenav-container>` ,
121+ } )
122+ class IndirectDescendantSidenav {
123+ @ViewChild ( 'container' , { static : false } ) container : MatSidenavContainer ;
124+ @ViewChild ( 'sidenav' , { static : false } ) sidenav : MatSidenav ;
125+ }
126+
127+ @Component ( {
128+ template : `
129+ <mat-sidenav-container #outerContainer>
130+ <mat-sidenav #outerSidenav>Sidenav</mat-sidenav>
131+ <mat-sidenav-content>
132+ <mat-sidenav-container #innerContainer>
133+ <mat-sidenav #innerSidenav>Sidenav</mat-sidenav>
134+ </mat-sidenav-container>
135+ </mat-sidenav-content>
136+ </mat-sidenav-container>
137+ ` ,
138+ } )
139+ class NestedSidenavContainers {
140+ @ViewChild ( 'outerContainer' , { static : false } ) outerContainer : MatSidenavContainer ;
141+ @ViewChild ( 'outerSidenav' , { static : false } ) outerSidenav : MatSidenav ;
142+ @ViewChild ( 'innerContainer' , { static : false } ) innerContainer : MatSidenavContainer ;
143+ @ViewChild ( 'innerSidenav' , { static : false } ) innerSidenav : MatSidenav ;
144+ }
0 commit comments