77 */
88
99import { fakeAsync , tick } from '@angular/core/testing' ;
10- import { DefaultUrlSerializer , NavigationEnd , NavigationStart , RouterEvent } from '@angular/router' ;
10+ import { DefaultUrlSerializer , Event , NavigationEnd , NavigationStart } from '@angular/router' ;
1111import { Subject } from 'rxjs' ;
12- import { filter , switchMap } from 'rxjs/operators' ;
12+ import { filter , switchMap , take } from 'rxjs/operators' ;
1313
1414import { Scroll } from '../src/events' ;
1515import { RouterScroller } from '../src/router_scroller' ;
1616
1717// TODO: add tests that exercise the `withInMemoryScrolling` feature of the provideRouter function
18+ const fakeZone = {
19+ runOutsideAngular : ( fn : any ) => fn ( ) ,
20+ run : ( fn : any ) => fn ( )
21+ } ;
1822describe ( 'RouterScroller' , ( ) => {
1923 it ( 'defaults to disabled' , ( ) => {
20- const events = new Subject < RouterEvent > ( ) ;
24+ const events = new Subject < Event > ( ) ;
2125 const router = < any > {
2226 events,
2327 parseUrl : ( url : any ) => new DefaultUrlSerializer ( ) . parse ( url ) ,
@@ -28,87 +32,103 @@ describe('RouterScroller', () => {
2832 'viewportScroller' ,
2933 [ 'getScrollPosition' , 'scrollToPosition' , 'scrollToAnchor' , 'setHistoryScrollRestoration' ] ) ;
3034 setScroll ( viewportScroller , 0 , 0 ) ;
31- const scroller = new RouterScroller ( router , router ) ;
35+ const scroller = new RouterScroller ( router , router , fakeZone as any ) ;
3236
3337 expect ( ( scroller as any ) . options . scrollPositionRestoration ) . toBe ( 'disabled' ) ;
3438 expect ( ( scroller as any ) . options . anchorScrolling ) . toBe ( 'disabled' ) ;
3539 } ) ;
3640
41+ function nextScrollEvent ( events : Subject < Event > ) : Promise < Scroll > {
42+ return events . pipe ( filter ( ( e ) : e is Scroll => e instanceof Scroll ) , take ( 1 ) ) . toPromise ( ) ;
43+ }
44+
3745 describe ( 'scroll to top' , ( ) => {
38- it ( 'should scroll to the top' , ( ) => {
46+ it ( 'should scroll to the top' , async ( ) => {
3947 const { events, viewportScroller} =
4048 createRouterScroller ( { scrollPositionRestoration : 'top' , anchorScrolling : 'disabled' } ) ;
4149
4250 events . next ( new NavigationStart ( 1 , '/a' ) ) ;
4351 events . next ( new NavigationEnd ( 1 , '/a' , '/a' ) ) ;
52+ await nextScrollEvent ( events ) ;
4453 expect ( viewportScroller . scrollToPosition ) . toHaveBeenCalledWith ( [ 0 , 0 ] ) ;
4554
4655 events . next ( new NavigationStart ( 2 , '/a' ) ) ;
4756 events . next ( new NavigationEnd ( 2 , '/b' , '/b' ) ) ;
57+ await nextScrollEvent ( events ) ;
4858 expect ( viewportScroller . scrollToPosition ) . toHaveBeenCalledWith ( [ 0 , 0 ] ) ;
4959
5060 events . next ( new NavigationStart ( 3 , '/a' , 'popstate' ) ) ;
5161 events . next ( new NavigationEnd ( 3 , '/a' , '/a' ) ) ;
62+ await nextScrollEvent ( events ) ;
5263 expect ( viewportScroller . scrollToPosition ) . toHaveBeenCalledWith ( [ 0 , 0 ] ) ;
5364 } ) ;
5465 } ) ;
5566
5667 describe ( 'scroll to the stored position' , ( ) => {
57- it ( 'should scroll to the stored position on popstate' , ( ) => {
68+ it ( 'should scroll to the stored position on popstate' , async ( ) => {
5869 const { events, viewportScroller} =
5970 createRouterScroller ( { scrollPositionRestoration : 'enabled' , anchorScrolling : 'disabled' } ) ;
6071
6172 events . next ( new NavigationStart ( 1 , '/a' ) ) ;
6273 events . next ( new NavigationEnd ( 1 , '/a' , '/a' ) ) ;
74+ await nextScrollEvent ( events ) ;
6375 setScroll ( viewportScroller , 10 , 100 ) ;
6476 expect ( viewportScroller . scrollToPosition ) . toHaveBeenCalledWith ( [ 0 , 0 ] ) ;
6577
6678 events . next ( new NavigationStart ( 2 , '/b' ) ) ;
6779 events . next ( new NavigationEnd ( 2 , '/b' , '/b' ) ) ;
80+ await nextScrollEvent ( events ) ;
6881 setScroll ( viewportScroller , 20 , 200 ) ;
6982 expect ( viewportScroller . scrollToPosition ) . toHaveBeenCalledWith ( [ 0 , 0 ] ) ;
7083
7184 events . next ( new NavigationStart ( 3 , '/a' , 'popstate' , { navigationId : 1 } ) ) ;
7285 events . next ( new NavigationEnd ( 3 , '/a' , '/a' ) ) ;
86+ await nextScrollEvent ( events ) ;
7387 expect ( viewportScroller . scrollToPosition ) . toHaveBeenCalledWith ( [ 10 , 100 ] ) ;
7488 } ) ;
7589 } ) ;
7690
7791 describe ( 'anchor scrolling' , ( ) => {
78- it ( 'should work (scrollPositionRestoration is disabled)' , ( ) => {
92+ it ( 'should work (scrollPositionRestoration is disabled)' , async ( ) => {
7993 const { events, viewportScroller} =
8094 createRouterScroller ( { scrollPositionRestoration : 'disabled' , anchorScrolling : 'enabled' } ) ;
8195 events . next ( new NavigationStart ( 1 , '/a#anchor' ) ) ;
8296 events . next ( new NavigationEnd ( 1 , '/a#anchor' , '/a#anchor' ) ) ;
97+ await nextScrollEvent ( events ) ;
8398 expect ( viewportScroller . scrollToAnchor ) . toHaveBeenCalledWith ( 'anchor' ) ;
8499
85100 events . next ( new NavigationStart ( 2 , '/a#anchor2' ) ) ;
86101 events . next ( new NavigationEnd ( 2 , '/a#anchor2' , '/a#anchor2' ) ) ;
102+ await nextScrollEvent ( events ) ;
87103 expect ( viewportScroller . scrollToAnchor ) . toHaveBeenCalledWith ( 'anchor2' ) ;
88104 viewportScroller . scrollToAnchor . calls . reset ( ) ;
89105
90106 // we never scroll to anchor when navigating back.
91107 events . next ( new NavigationStart ( 3 , '/a#anchor' , 'popstate' ) ) ;
92108 events . next ( new NavigationEnd ( 3 , '/a#anchor' , '/a#anchor' ) ) ;
109+ await nextScrollEvent ( events ) ;
93110 expect ( viewportScroller . scrollToAnchor ) . not . toHaveBeenCalled ( ) ;
94111 expect ( viewportScroller . scrollToPosition ) . not . toHaveBeenCalled ( ) ;
95112 } ) ;
96113
97- it ( 'should work (scrollPositionRestoration is enabled)' , ( ) => {
114+ it ( 'should work (scrollPositionRestoration is enabled)' , async ( ) => {
98115 const { events, viewportScroller} =
99116 createRouterScroller ( { scrollPositionRestoration : 'enabled' , anchorScrolling : 'enabled' } ) ;
100117 events . next ( new NavigationStart ( 1 , '/a#anchor' ) ) ;
101118 events . next ( new NavigationEnd ( 1 , '/a#anchor' , '/a#anchor' ) ) ;
119+ await nextScrollEvent ( events ) ;
102120 expect ( viewportScroller . scrollToAnchor ) . toHaveBeenCalledWith ( 'anchor' ) ;
103121
104122 events . next ( new NavigationStart ( 2 , '/a#anchor2' ) ) ;
105123 events . next ( new NavigationEnd ( 2 , '/a#anchor2' , '/a#anchor2' ) ) ;
124+ await nextScrollEvent ( events ) ;
106125 expect ( viewportScroller . scrollToAnchor ) . toHaveBeenCalledWith ( 'anchor2' ) ;
107126 viewportScroller . scrollToAnchor . calls . reset ( ) ;
108127
109128 // we never scroll to anchor when navigating back
110129 events . next ( new NavigationStart ( 3 , '/a#anchor' , 'popstate' , { navigationId : 1 } ) ) ;
111130 events . next ( new NavigationEnd ( 3 , '/a#anchor' , '/a#anchor' ) ) ;
131+ await nextScrollEvent ( events ) ;
112132 expect ( viewportScroller . scrollToAnchor ) . not . toHaveBeenCalled ( ) ;
113133 expect ( viewportScroller . scrollToPosition ) . toHaveBeenCalledWith ( [ 0 , 0 ] ) ;
114134 } ) ;
@@ -135,14 +155,17 @@ describe('RouterScroller', () => {
135155
136156 events . next ( new NavigationStart ( 1 , '/a' ) ) ;
137157 events . next ( new NavigationEnd ( 1 , '/a' , '/a' ) ) ;
158+ tick ( ) ;
138159 setScroll ( viewportScroller , 10 , 100 ) ;
139160
140161 events . next ( new NavigationStart ( 2 , '/b' ) ) ;
141162 events . next ( new NavigationEnd ( 2 , '/b' , '/b' ) ) ;
163+ tick ( ) ;
142164 setScroll ( viewportScroller , 20 , 200 ) ;
143165
144166 events . next ( new NavigationStart ( 3 , '/c' ) ) ;
145167 events . next ( new NavigationEnd ( 3 , '/c' , '/c' ) ) ;
168+ tick ( ) ;
146169 setScroll ( viewportScroller , 30 , 300 ) ;
147170
148171 events . next ( new NavigationStart ( 4 , '/a' , 'popstate' , { navigationId : 1 } ) ) ;
@@ -164,7 +187,7 @@ describe('RouterScroller', () => {
164187 scrollPositionRestoration : 'disabled' | 'enabled' | 'top' ,
165188 anchorScrolling : 'disabled' | 'enabled'
166189 } ) {
167- const events = new Subject < RouterEvent > ( ) ;
190+ const events = new Subject < Event > ( ) ;
168191 const router = < any > {
169192 events,
170193 parseUrl : ( url : any ) => new DefaultUrlSerializer ( ) . parse ( url ) ,
@@ -176,8 +199,8 @@ describe('RouterScroller', () => {
176199 [ 'getScrollPosition' , 'scrollToPosition' , 'scrollToAnchor' , 'setHistoryScrollRestoration' ] ) ;
177200 setScroll ( viewportScroller , 0 , 0 ) ;
178201
179- const scroller =
180- new RouterScroller ( router , viewportScroller , { scrollPositionRestoration, anchorScrolling} ) ;
202+ const scroller = new RouterScroller (
203+ router , viewportScroller , fakeZone as any , { scrollPositionRestoration, anchorScrolling} ) ;
181204 scroller . init ( ) ;
182205
183206 return { events, viewportScroller, router} ;
0 commit comments