From 8ce59a583b7041841e6a3a49ebdb23eff06c9cdd Mon Sep 17 00:00:00 2001 From: Marc Laval Date: Tue, 20 Nov 2018 17:02:35 +0100 Subject: [PATCH] test(ivy): run router tests with ivy on CI (#27195) PR Close #27195 --- packages/router/karma-test-shim.js | 1 + packages/router/karma.conf.js | 2 + packages/router/test/BUILD.bazel | 7 +- packages/router/test/integration.spec.ts | 3704 +++++++++-------- .../operators/prioritized_guard_value.spec.ts | 2 +- .../test/regression_integration.spec.ts | 124 +- packages/router/test/router.spec.ts | 2 +- packages/router/test/router_preloader.spec.ts | 257 +- .../test/spy_ng_module_factory_loader.spec.ts | 2 +- 9 files changed, 2108 insertions(+), 1993 deletions(-) diff --git a/packages/router/karma-test-shim.js b/packages/router/karma-test-shim.js index 2d4304e5a0..d10f13a5d7 100644 --- a/packages/router/karma-test-shim.js +++ b/packages/router/karma-test-shim.js @@ -51,6 +51,7 @@ System.config({ '@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'}, '@angular/platform-browser-dynamic/testing': {main: 'index.js', defaultExtension: 'js'}, '@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'}, + '@angular/private/testing': {main: 'index.js', defaultExtension: 'js'}, '@angular/upgrade/static': {main: 'index.js', defaultExtension: 'js'}, '@angular/router/upgrade': {main: 'index.js', defaultExtension: 'js'}, '@angular/router/testing': {main: 'index.js', defaultExtension: 'js'}, diff --git a/packages/router/karma.conf.js b/packages/router/karma.conf.js index 758973b9ce..a283ff240f 100644 --- a/packages/router/karma.conf.js +++ b/packages/router/karma.conf.js @@ -76,6 +76,8 @@ module.exports = function(config) { watched: false }, + {pattern: 'dist/all/@angular/private/testing/**/*.js', included: false, watched: false}, + {pattern: 'dist/all/@angular/upgrade/static/*.js', included: false, watched: false}, {pattern: 'dist/all/@angular/upgrade/static/src/**/*.js', included: false, watched: false}, diff --git a/packages/router/test/BUILD.bazel b/packages/router/test/BUILD.bazel index 6c9925f584..15be00ff80 100644 --- a/packages/router/test/BUILD.bazel +++ b/packages/router/test/BUILD.bazel @@ -12,6 +12,7 @@ ts_library( "//packages/platform-browser", "//packages/platform-browser-dynamic", "//packages/platform-browser/testing", + "//packages/private/testing", "//packages/router", "//packages/router/testing", "@rxjs", @@ -23,9 +24,6 @@ ts_library( jasmine_node_test( name = "test", bootstrap = ["angular/tools/testing/init_node_spec.js"], - tags = [ - "fixme-ivy-aot", - ], deps = [ ":test_lib", "//tools/testing:node", @@ -34,9 +32,6 @@ jasmine_node_test( ts_web_test_suite( name = "test_web", - tags = [ - "fixme-ivy-aot", - ], deps = [ ":test_lib", ], diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index 4fc5d82993..03657fe01a 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -12,6 +12,7 @@ import {ChangeDetectionStrategy, Component, Injectable, NgModule, NgModuleFactor import {ComponentFixture, TestBed, fakeAsync, flush, inject, tick} from '@angular/core/testing'; import {By} from '@angular/platform-browser/src/dom/debug/by'; import {expect} from '@angular/platform-browser/testing/src/matchers'; +import {fixmeIvy} from '@angular/private/testing'; import {ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, CanActivate, CanDeactivate, ChildActivationEnd, ChildActivationStart, DetachedRouteHandle, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterModule, RouterPreloader, RouterStateSnapshot, RoutesRecognized, RunGuardsAndResolvers, UrlHandlingStrategy, UrlSegmentGroup, UrlSerializer, UrlTree} from '@angular/router'; import {Observable, Observer, Subscription, of } from 'rxjs'; import {filter, first, map, tap} from 'rxjs/operators'; @@ -296,33 +297,34 @@ describe('Integration', () => { beforeEach(() => TestBed.configureTestingModule({imports: [TestModule]})); - it('should work', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should work', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'parent/:id', - component: Parent, - children: [ - {path: 'child1', component: Child1}, - {path: 'child2', component: Child2}, - ] - }]); + router.resetConfig([{ + path: 'parent/:id', + component: Parent, + children: [ + {path: 'child1', component: Child1}, + {path: 'child2', component: Child2}, + ] + }]); - router.navigateByUrl('/parent/1/child1'); - advance(fixture); + router.navigateByUrl('/parent/1/child1'); + advance(fixture); - router.navigateByUrl('/parent/2/child2'); - advance(fixture); + router.navigateByUrl('/parent/2/child2'); + advance(fixture); - expect(location.path()).toEqual('/parent/2/child2'); - expect(log).toEqual([ - {id: '1'}, - 'child1 destroy', - {id: '2'}, - 'child2 constructor', - ]); - }))); + expect(location.path()).toEqual('/parent/2/child2'); + expect(log).toEqual([ + {id: '1'}, + 'child1 destroy', + {id: '2'}, + 'child2 constructor', + ]); + }))); }); @@ -401,285 +403,297 @@ describe('Integration', () => { expect(fixture.nativeElement).toHaveText('it works!'); })); - it('should not error when no url left and no children are matching', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); - - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [{path: 'simple', component: SimpleCmp}] - }]); + fixmeIvy('FW-???: assertion failures') && + it('should not error when no url left and no children are matching', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [{path: 'simple', component: SimpleCmp}] + }]); + + router.navigateByUrl('/team/33/simple'); + advance(fixture); + + expect(location.path()).toEqual('/team/33/simple'); + expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); + + router.navigateByUrl('/team/33'); + advance(fixture); + + expect(location.path()).toEqual('/team/33'); + expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); + }))); + + fixmeIvy('FW-???: Error: Timeout') && + it('should work when an outlet is in an ngIf', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.navigateByUrl('/team/33/simple'); - advance(fixture); + router.resetConfig([{ + path: 'child', + component: OutletInNgIf, + children: [{path: 'simple', component: SimpleCmp}] + }]); - expect(location.path()).toEqual('/team/33/simple'); - expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); + router.navigateByUrl('/child/simple'); + advance(fixture); - router.navigateByUrl('/team/33'); - advance(fixture); + expect(location.path()).toEqual('/child/simple'); + }))); - expect(location.path()).toEqual('/team/33'); - expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); - }))); + fixmeIvy('FW-???: Error: 1 timer(s) still in the queue.') && + it('should work when an outlet is added/removed', fakeAsync(() => { + @Component({ + selector: 'someRoot', + template: `[
]` + }) + class RootCmpWithLink { + cond: boolean = true; + } + TestBed.configureTestingModule({declarations: [RootCmpWithLink]}); - it('should work when an outlet is in an ngIf', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + const router: Router = TestBed.get(Router); - router.resetConfig([{ - path: 'child', - component: OutletInNgIf, - children: [{path: 'simple', component: SimpleCmp}] - }]); + const fixture = createRoot(router, RootCmpWithLink); - router.navigateByUrl('/child/simple'); - advance(fixture); + router.resetConfig([ + {path: 'simple', component: SimpleCmp}, + {path: 'blank', component: BlankCmp}, + ]); - expect(location.path()).toEqual('/child/simple'); - }))); + router.navigateByUrl('/simple'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('[simple]'); - it('should work when an outlet is added/removed', fakeAsync(() => { - @Component({ - selector: 'someRoot', - template: `[
]` - }) - class RootCmpWithLink { - cond: boolean = true; - } - TestBed.configureTestingModule({declarations: [RootCmpWithLink]}); + fixture.componentInstance.cond = false; + advance(fixture); + expect(fixture.nativeElement).toHaveText('[]'); - const router: Router = TestBed.get(Router); + fixture.componentInstance.cond = true; + advance(fixture); + expect(fixture.nativeElement).toHaveText('[simple]'); + })); - const fixture = createRoot(router, RootCmpWithLink); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should update location when navigating', fakeAsync(() => { + @Component({template: `record`}) + class RecordLocationCmp { + private storedPath: string; + constructor(loc: Location) { this.storedPath = loc.path(); } + } - router.resetConfig([ - {path: 'simple', component: SimpleCmp}, - {path: 'blank', component: BlankCmp}, - ]); + @NgModule({declarations: [RecordLocationCmp], entryComponents: [RecordLocationCmp]}) + class TestModule { + } - router.navigateByUrl('/simple'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('[simple]'); + TestBed.configureTestingModule({imports: [TestModule]}); + + const router = TestBed.get(Router); + const location = TestBed.get(Location); + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{path: 'record/:id', component: RecordLocationCmp}]); + + router.navigateByUrl('/record/22'); + advance(fixture); + + const c = fixture.debugElement.children[1].componentInstance; + expect(location.path()).toEqual('/record/22'); + expect(c.storedPath).toEqual('/record/22'); + + router.navigateByUrl('/record/33'); + advance(fixture); + expect(location.path()).toEqual('/record/33'); + })); - fixture.componentInstance.cond = false; - advance(fixture); - expect(fixture.nativeElement).toHaveText('[]'); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should skip location update when using NavigationExtras.skipLocationChange with navigateByUrl', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = TestBed.createComponent(RootCmp); + advance(fixture); - fixture.componentInstance.cond = true; - advance(fixture); - expect(fixture.nativeElement).toHaveText('[simple]'); - })); + router.resetConfig([{path: 'team/:id', component: TeamCmp}]); - it('should update location when navigating', fakeAsync(() => { - @Component({template: `record`}) - class RecordLocationCmp { - private storedPath: string; - constructor(loc: Location) { this.storedPath = loc.path(); } - } + router.navigateByUrl('/team/22'); + advance(fixture); + expect(location.path()).toEqual('/team/22'); + + expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); + + router.navigateByUrl('/team/33', {skipLocationChange: true}); + advance(fixture); + + expect(location.path()).toEqual('/team/22'); + + expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); + }))); + + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should skip location update when using NavigationExtras.skipLocationChange with navigate', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = TestBed.createComponent(RootCmp); + advance(fixture); - @NgModule({declarations: [RecordLocationCmp], entryComponents: [RecordLocationCmp]}) - class TestModule { - } + router.resetConfig([{path: 'team/:id', component: TeamCmp}]); + + router.navigate(['/team/22']); + advance(fixture); + expect(location.path()).toEqual('/team/22'); + + expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); + + router.navigate(['/team/33'], {skipLocationChange: true}); + advance(fixture); + + expect(location.path()).toEqual('/team/22'); + + expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); + }))); - TestBed.configureTestingModule({imports: [TestModule]}); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should eagerly update the URL with urlUpdateStrategy="eagar"', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = TestBed.createComponent(RootCmp); + advance(fixture); - const router = TestBed.get(Router); - const location = TestBed.get(Location); - const fixture = createRoot(router, RootCmp); + router.resetConfig([{path: 'team/:id', component: TeamCmp}]); + + router.navigateByUrl('/team/22'); + advance(fixture); + expect(location.path()).toEqual('/team/22'); - router.resetConfig([{path: 'record/:id', component: RecordLocationCmp}]); + expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); - router.navigateByUrl('/record/22'); - advance(fixture); + router.urlUpdateStrategy = 'eager'; + (router as any).hooks.beforePreactivation = () => { + expect(location.path()).toEqual('/team/33'); + expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); + return of (null); + }; + router.navigateByUrl('/team/33'); - const c = fixture.debugElement.children[1].componentInstance; - expect(location.path()).toEqual('/record/22'); - expect(c.storedPath).toEqual('/record/22'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); + }))); - router.navigateByUrl('/record/33'); - advance(fixture); - expect(location.path()).toEqual('/record/33'); - })); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should navigate back and forward', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - it('should skip location update when using NavigationExtras.skipLocationChange with navigateByUrl', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = TestBed.createComponent(RootCmp); - advance(fixture); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp} + ] + }]); - router.resetConfig([{path: 'team/:id', component: TeamCmp}]); + let event: NavigationStart; + router.events.subscribe(e => { + if (e instanceof NavigationStart) { + event = e; + } + }); + + router.navigateByUrl('/team/33/simple'); + advance(fixture); + expect(location.path()).toEqual('/team/33/simple'); + const simpleNavStart = event !; - router.navigateByUrl('/team/22'); - advance(fixture); - expect(location.path()).toEqual('/team/22'); + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); + const userVictorNavStart = event !; - expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); - router.navigateByUrl('/team/33', {skipLocationChange: true}); - advance(fixture); + location.back(); + advance(fixture); + expect(location.path()).toEqual('/team/33/simple'); + expect(event !.navigationTrigger).toEqual('hashchange'); + expect(event !.restoredState !.navigationId).toEqual(simpleNavStart.id); - expect(location.path()).toEqual('/team/22'); - - expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); - }))); - - it('should skip location update when using NavigationExtras.skipLocationChange with navigate', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = TestBed.createComponent(RootCmp); - advance(fixture); - - router.resetConfig([{path: 'team/:id', component: TeamCmp}]); - - router.navigate(['/team/22']); - advance(fixture); - expect(location.path()).toEqual('/team/22'); - - expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); - - router.navigate(['/team/33'], {skipLocationChange: true}); - advance(fixture); - - expect(location.path()).toEqual('/team/22'); - - expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); - }))); - - it('should eagerly update the URL with urlUpdateStrategy="eagar"', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = TestBed.createComponent(RootCmp); - advance(fixture); - - router.resetConfig([{path: 'team/:id', component: TeamCmp}]); - - router.navigateByUrl('/team/22'); - advance(fixture); - expect(location.path()).toEqual('/team/22'); - - expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); - - router.urlUpdateStrategy = 'eager'; - (router as any).hooks.beforePreactivation = () => { - expect(location.path()).toEqual('/team/33'); - expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); - return of (null); - }; - router.navigateByUrl('/team/33'); - - advance(fixture); - expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); - }))); - - it('should navigate back and forward', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); - - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: - [{path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp}] - }]); - - let event: NavigationStart; - router.events.subscribe(e => { - if (e instanceof NavigationStart) { - event = e; - } - }); - - router.navigateByUrl('/team/33/simple'); - advance(fixture); - expect(location.path()).toEqual('/team/33/simple'); - const simpleNavStart = event !; - - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); - const userVictorNavStart = event !; - - - location.back(); - advance(fixture); - expect(location.path()).toEqual('/team/33/simple'); - expect(event !.navigationTrigger).toEqual('hashchange'); - expect(event !.restoredState !.navigationId).toEqual(simpleNavStart.id); - - location.forward(); - advance(fixture); - expect(location.path()).toEqual('/team/22/user/victor'); - expect(event !.navigationTrigger).toEqual('hashchange'); - expect(event !.restoredState !.navigationId).toEqual(userVictorNavStart.id); - }))); - - it('should navigate to the same url when config changes', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); - - router.resetConfig([{path: 'a', component: SimpleCmp}]); - - router.navigate(['/a']); - advance(fixture); - expect(location.path()).toEqual('/a'); - expect(fixture.nativeElement).toHaveText('simple'); - - router.resetConfig([{path: 'a', component: RouteCmp}]); - - router.navigate(['/a']); - advance(fixture); - expect(location.path()).toEqual('/a'); - expect(fixture.nativeElement).toHaveText('route'); - }))); - - it('should navigate when locations changes', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); - - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [{path: 'user/:name', component: UserCmp}] - }]); - - const recordedEvents: any[] = []; - router.events.forEach(e => onlyNavigationStartAndEnd(e) && recordedEvents.push(e)); - - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); - - (location).simulateHashChange('/team/22/user/fedor'); - advance(fixture); - - (location).simulateUrlPop('/team/22/user/fedor'); - advance(fixture); - - expect(fixture.nativeElement).toHaveText('team 22 [ user fedor, right: ]'); - - expectEvents(recordedEvents, [ - [NavigationStart, '/team/22/user/victor'], [NavigationEnd, '/team/22/user/victor'], - [NavigationStart, '/team/22/user/fedor'], [NavigationEnd, '/team/22/user/fedor'] - ]); - }))); - - it('should update the location when the matched route does not change', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); - - router.resetConfig([{path: '**', component: CollectParamsCmp}]); - - router.navigateByUrl('/one/two'); - advance(fixture); - const cmp = fixture.debugElement.children[1].componentInstance; - expect(location.path()).toEqual('/one/two'); - expect(fixture.nativeElement).toHaveText('collect-params'); - - expect(cmp.recordedUrls()).toEqual(['one/two']); - - router.navigateByUrl('/three/four'); - advance(fixture); - expect(location.path()).toEqual('/three/four'); - expect(fixture.nativeElement).toHaveText('collect-params'); - expect(cmp.recordedUrls()).toEqual(['one/two', 'three/four']); - }))); + location.forward(); + advance(fixture); + expect(location.path()).toEqual('/team/22/user/victor'); + expect(event !.navigationTrigger).toEqual('hashchange'); + expect(event !.restoredState !.navigationId).toEqual(userVictorNavStart.id); + }))); + + fixmeIvy('FW-???: assertion failures') && + it('should navigate to the same url when config changes', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{path: 'a', component: SimpleCmp}]); + + router.navigate(['/a']); + advance(fixture); + expect(location.path()).toEqual('/a'); + expect(fixture.nativeElement).toHaveText('simple'); + + router.resetConfig([{path: 'a', component: RouteCmp}]); + + router.navigate(['/a']); + advance(fixture); + expect(location.path()).toEqual('/a'); + expect(fixture.nativeElement).toHaveText('route'); + }))); + + fixmeIvy('FW-???: assertion failures') && + it('should navigate when locations changes', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [{path: 'user/:name', component: UserCmp}] + }]); + + const recordedEvents: any[] = []; + router.events.forEach(e => onlyNavigationStartAndEnd(e) && recordedEvents.push(e)); + + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); + + (location).simulateHashChange('/team/22/user/fedor'); + advance(fixture); + + (location).simulateUrlPop('/team/22/user/fedor'); + advance(fixture); + + expect(fixture.nativeElement).toHaveText('team 22 [ user fedor, right: ]'); + + expectEvents(recordedEvents, [ + [NavigationStart, '/team/22/user/victor'], [NavigationEnd, '/team/22/user/victor'], + [NavigationStart, '/team/22/user/fedor'], [NavigationEnd, '/team/22/user/fedor'] + ]); + }))); + + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should update the location when the matched route does not change', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{path: '**', component: CollectParamsCmp}]); + + router.navigateByUrl('/one/two'); + advance(fixture); + const cmp = fixture.debugElement.children[1].componentInstance; + expect(location.path()).toEqual('/one/two'); + expect(fixture.nativeElement).toHaveText('collect-params'); + + expect(cmp.recordedUrls()).toEqual(['one/two']); + + router.navigateByUrl('/three/four'); + advance(fixture); + expect(location.path()).toEqual('/three/four'); + expect(fixture.nativeElement).toHaveText('collect-params'); + expect(cmp.recordedUrls()).toEqual(['one/two', 'three/four']); + }))); describe('should reset location if a navigation by location is successful', () => { beforeEach(() => { @@ -718,115 +732,121 @@ describe('Integration', () => { }))); }); - it('should support secondary routes', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support secondary routes', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'user/:name', component: UserCmp}, - {path: 'simple', component: SimpleCmp, outlet: 'right'} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'user/:name', component: UserCmp}, + {path: 'simple', component: SimpleCmp, outlet: 'right'} + ] + }]); - router.navigateByUrl('/team/22/(user/victor//right:simple)'); - advance(fixture); + router.navigateByUrl('/team/22/(user/victor//right:simple)'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); - }))); + expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); + }))); - it('should support secondary routes in separate commands', - fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support secondary routes in separate commands', + fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'user/:name', component: UserCmp}, - {path: 'simple', component: SimpleCmp, outlet: 'right'} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'user/:name', component: UserCmp}, + {path: 'simple', component: SimpleCmp, outlet: 'right'} + ] + }]); - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); - router.navigate(['team/22', {outlets: {right: 'simple'}}]); - advance(fixture); + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); + router.navigate(['team/22', {outlets: {right: 'simple'}}]); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); - }))); + expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); + }))); - it('should deactivate outlets', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should deactivate outlets', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'user/:name', component: UserCmp}, - {path: 'simple', component: SimpleCmp, outlet: 'right'} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'user/:name', component: UserCmp}, + {path: 'simple', component: SimpleCmp, outlet: 'right'} + ] + }]); - router.navigateByUrl('/team/22/(user/victor//right:simple)'); - advance(fixture); + router.navigateByUrl('/team/22/(user/victor//right:simple)'); + advance(fixture); - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: ]'); - }))); + expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: ]'); + }))); - it('should deactivate nested outlets', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should deactivate nested outlets', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - { - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'user/:name', component: UserCmp}, - {path: 'simple', component: SimpleCmp, outlet: 'right'} - ] - }, - {path: '', component: BlankCmp} - ]); + router.resetConfig([ + { + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'user/:name', component: UserCmp}, + {path: 'simple', component: SimpleCmp, outlet: 'right'} + ] + }, + {path: '', component: BlankCmp} + ]); - router.navigateByUrl('/team/22/(user/victor//right:simple)'); - advance(fixture); + router.navigateByUrl('/team/22/(user/victor//right:simple)'); + advance(fixture); - router.navigateByUrl('/'); - advance(fixture); + router.navigateByUrl('/'); + advance(fixture); - expect(fixture.nativeElement).toHaveText(''); - }))); + expect(fixture.nativeElement).toHaveText(''); + }))); - it('should set query params and fragment', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should set query params and fragment', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'query', component: QueryParamsAndFragmentCmp}]); + router.resetConfig([{path: 'query', component: QueryParamsAndFragmentCmp}]); - router.navigateByUrl('/query?name=1#fragment1'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('query: 1 fragment: fragment1'); + router.navigateByUrl('/query?name=1#fragment1'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('query: 1 fragment: fragment1'); - router.navigateByUrl('/query?name=2#fragment2'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('query: 2 fragment: fragment2'); - }))); + router.navigateByUrl('/query?name=2#fragment2'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('query: 2 fragment: fragment2'); + }))); - it('should ignore null and undefined query params', - fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should ignore null and undefined query params', + fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'query', component: EmptyQueryParamsCmp}]); + router.resetConfig([{path: 'query', component: EmptyQueryParamsCmp}]); - router.navigate(['query'], {queryParams: {name: 1, age: null, page: undefined}}); - advance(fixture); - const cmp = fixture.debugElement.children[1].componentInstance; - expect(cmp.recordedParams).toEqual([{name: '1'}]); - }))); + router.navigate(['query'], {queryParams: {name: 1, age: null, page: undefined}}); + advance(fixture); + const cmp = fixture.debugElement.children[1].componentInstance; + expect(cmp.recordedParams).toEqual([{name: '1'}]); + }))); it('should throw an error when one of the commands is null/undefined', fakeAsync(inject([Router], (router: Router) => { @@ -839,106 +859,110 @@ describe('Integration', () => { ])).toThrowError(`The requested path contains undefined segment at index 0`); }))); - it('should push params only when they change', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should push params only when they change', + fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [{path: 'user/:name', component: UserCmp}] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [{path: 'user/:name', component: UserCmp}] + }]); - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); - const team = fixture.debugElement.children[1].componentInstance; - const user = fixture.debugElement.children[1].children[1].componentInstance; + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); + const team = fixture.debugElement.children[1].componentInstance; + const user = fixture.debugElement.children[1].children[1].componentInstance; - expect(team.recordedParams).toEqual([{id: '22'}]); - expect(team.snapshotParams).toEqual([{id: '22'}]); - expect(user.recordedParams).toEqual([{name: 'victor'}]); - expect(user.snapshotParams).toEqual([{name: 'victor'}]); + expect(team.recordedParams).toEqual([{id: '22'}]); + expect(team.snapshotParams).toEqual([{id: '22'}]); + expect(user.recordedParams).toEqual([{name: 'victor'}]); + expect(user.snapshotParams).toEqual([{name: 'victor'}]); - router.navigateByUrl('/team/22/user/fedor'); - advance(fixture); + router.navigateByUrl('/team/22/user/fedor'); + advance(fixture); - expect(team.recordedParams).toEqual([{id: '22'}]); - expect(team.snapshotParams).toEqual([{id: '22'}]); - expect(user.recordedParams).toEqual([{name: 'victor'}, {name: 'fedor'}]); - expect(user.snapshotParams).toEqual([{name: 'victor'}, {name: 'fedor'}]); - }))); + expect(team.recordedParams).toEqual([{id: '22'}]); + expect(team.snapshotParams).toEqual([{id: '22'}]); + expect(user.recordedParams).toEqual([{name: 'victor'}, {name: 'fedor'}]); + expect(user.snapshotParams).toEqual([{name: 'victor'}, {name: 'fedor'}]); + }))); - it('should work when navigating to /', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should work when navigating to /', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - {path: '', pathMatch: 'full', component: SimpleCmp}, - {path: 'user/:name', component: UserCmp} - ]); + router.resetConfig([ + {path: '', pathMatch: 'full', component: SimpleCmp}, + {path: 'user/:name', component: UserCmp} + ]); - router.navigateByUrl('/user/victor'); - advance(fixture); + router.navigateByUrl('/user/victor'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('user victor'); + expect(fixture.nativeElement).toHaveText('user victor'); - router.navigateByUrl('/'); - advance(fixture); + router.navigateByUrl('/'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('simple'); - }))); + expect(fixture.nativeElement).toHaveText('simple'); + }))); - it('should cancel in-flight navigations', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should cancel in-flight navigations', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'user/:name', component: UserCmp}]); + router.resetConfig([{path: 'user/:name', component: UserCmp}]); - const recordedEvents: any[] = []; - router.events.forEach(e => recordedEvents.push(e)); + const recordedEvents: any[] = []; + router.events.forEach(e => recordedEvents.push(e)); - router.navigateByUrl('/user/init'); - advance(fixture); + router.navigateByUrl('/user/init'); + advance(fixture); - const user = fixture.debugElement.children[1].componentInstance; + const user = fixture.debugElement.children[1].componentInstance; - let r1: any, r2: any; - router.navigateByUrl('/user/victor') !.then(_ => r1 = _); - router.navigateByUrl('/user/fedor') !.then(_ => r2 = _); - advance(fixture); + let r1: any, r2: any; + router.navigateByUrl('/user/victor') !.then(_ => r1 = _); + router.navigateByUrl('/user/fedor') !.then(_ => r2 = _); + advance(fixture); - expect(r1).toEqual(false); // returns false because it was canceled - expect(r2).toEqual(true); // returns true because it was successful + expect(r1).toEqual(false); // returns false because it was canceled + expect(r2).toEqual(true); // returns true because it was successful - expect(fixture.nativeElement).toHaveText('user fedor'); - expect(user.recordedParams).toEqual([{name: 'init'}, {name: 'fedor'}]); + expect(fixture.nativeElement).toHaveText('user fedor'); + expect(user.recordedParams).toEqual([{name: 'init'}, {name: 'fedor'}]); - expectEvents(recordedEvents, [ - [NavigationStart, '/user/init'], - [RoutesRecognized, '/user/init'], - [GuardsCheckStart, '/user/init'], - [ChildActivationStart], - [ActivationStart], - [GuardsCheckEnd, '/user/init'], - [ResolveStart, '/user/init'], - [ResolveEnd, '/user/init'], - [ActivationEnd], - [ChildActivationEnd], - [NavigationEnd, '/user/init'], + expectEvents(recordedEvents, [ + [NavigationStart, '/user/init'], + [RoutesRecognized, '/user/init'], + [GuardsCheckStart, '/user/init'], + [ChildActivationStart], + [ActivationStart], + [GuardsCheckEnd, '/user/init'], + [ResolveStart, '/user/init'], + [ResolveEnd, '/user/init'], + [ActivationEnd], + [ChildActivationEnd], + [NavigationEnd, '/user/init'], - [NavigationStart, '/user/victor'], - [NavigationCancel, '/user/victor'], + [NavigationStart, '/user/victor'], + [NavigationCancel, '/user/victor'], - [NavigationStart, '/user/fedor'], - [RoutesRecognized, '/user/fedor'], - [GuardsCheckStart, '/user/fedor'], - [ChildActivationStart], - [ActivationStart], - [GuardsCheckEnd, '/user/fedor'], - [ResolveStart, '/user/fedor'], - [ResolveEnd, '/user/fedor'], - [ActivationEnd], - [ChildActivationEnd], - [NavigationEnd, '/user/fedor'] - ]); - }))); + [NavigationStart, '/user/fedor'], + [RoutesRecognized, '/user/fedor'], + [GuardsCheckStart, '/user/fedor'], + [ChildActivationStart], + [ActivationStart], + [GuardsCheckEnd, '/user/fedor'], + [ResolveStart, '/user/fedor'], + [ResolveEnd, '/user/fedor'], + [ActivationEnd], + [ChildActivationEnd], + [NavigationEnd, '/user/fedor'] + ]); + }))); it('should handle failed navigations gracefully', fakeAsync(inject([Router], (router: Router) => { const fixture = createRoot(router, RootCmp); @@ -1149,151 +1173,157 @@ describe('Integration', () => { }))); - it('should replace state when path is equal to current path', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should replace state when path is equal to current path', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: - [{path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp}] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp} + ] + }]); - router.navigateByUrl('/team/33/simple'); - advance(fixture); + router.navigateByUrl('/team/33/simple'); + advance(fixture); - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); - location.back(); - advance(fixture); - expect(location.path()).toEqual('/team/33/simple'); - }))); + location.back(); + advance(fixture); + expect(location.path()).toEqual('/team/33/simple'); + }))); - it('should handle componentless paths', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmpWithTwoOutlets); + fixmeIvy('FW-???: assertion failures') && + it('should handle componentless paths', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmpWithTwoOutlets); - router.resetConfig([ - { - path: 'parent/:id', - children: [ + router.resetConfig([ + { + path: 'parent/:id', + children: [ + {path: 'simple', component: SimpleCmp}, + {path: 'user/:name', component: UserCmp, outlet: 'right'} + ] + }, + {path: 'user/:name', component: UserCmp} + ]); + + + // navigate to a componentless route + router.navigateByUrl('/parent/11/(simple//right:user/victor)'); + advance(fixture); + expect(location.path()).toEqual('/parent/11/(simple//right:user/victor)'); + expect(fixture.nativeElement).toHaveText('primary [simple] right [user victor]'); + + // navigate to the same route with different params (reuse) + router.navigateByUrl('/parent/22/(simple//right:user/fedor)'); + advance(fixture); + expect(location.path()).toEqual('/parent/22/(simple//right:user/fedor)'); + expect(fixture.nativeElement).toHaveText('primary [simple] right [user fedor]'); + + // navigate to a normal route (check deactivation) + router.navigateByUrl('/user/victor'); + advance(fixture); + expect(location.path()).toEqual('/user/victor'); + expect(fixture.nativeElement).toHaveText('primary [user victor] right []'); + + // navigate back to a componentless route + router.navigateByUrl('/parent/11/(simple//right:user/victor)'); + advance(fixture); + expect(location.path()).toEqual('/parent/11/(simple//right:user/victor)'); + expect(fixture.nativeElement).toHaveText('primary [simple] right [user victor]'); + }))); + + fixmeIvy('FW-???: assertion failures') && + it('should not deactivate aux routes when navigating from a componentless routes', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, TwoOutletsCmp); + + router.resetConfig([ {path: 'simple', component: SimpleCmp}, - {path: 'user/:name', component: UserCmp, outlet: 'right'} - ] - }, - {path: 'user/:name', component: UserCmp} - ]); + {path: 'componentless', children: [{path: 'simple', component: SimpleCmp}]}, + {path: 'user/:name', outlet: 'aux', component: UserCmp} + ]); + router.navigateByUrl('/componentless/simple(aux:user/victor)'); + advance(fixture); + expect(location.path()).toEqual('/componentless/simple(aux:user/victor)'); + expect(fixture.nativeElement).toHaveText('[ simple, aux: user victor ]'); - // navigate to a componentless route - router.navigateByUrl('/parent/11/(simple//right:user/victor)'); - advance(fixture); - expect(location.path()).toEqual('/parent/11/(simple//right:user/victor)'); - expect(fixture.nativeElement).toHaveText('primary [simple] right [user victor]'); + router.navigateByUrl('/simple(aux:user/victor)'); + advance(fixture); + expect(location.path()).toEqual('/simple(aux:user/victor)'); + expect(fixture.nativeElement).toHaveText('[ simple, aux: user victor ]'); + }))); - // navigate to the same route with different params (reuse) - router.navigateByUrl('/parent/22/(simple//right:user/fedor)'); - advance(fixture); - expect(location.path()).toEqual('/parent/22/(simple//right:user/fedor)'); - expect(fixture.nativeElement).toHaveText('primary [simple] right [user fedor]'); + fixmeIvy('FW-???: assertion failures') && + it('should emit an event when an outlet gets activated', fakeAsync(() => { + @Component({ + selector: 'container', + template: + `` + }) + class Container { + activations: any[] = []; + deactivations: any[] = []; - // navigate to a normal route (check deactivation) - router.navigateByUrl('/user/victor'); - advance(fixture); - expect(location.path()).toEqual('/user/victor'); - expect(fixture.nativeElement).toHaveText('primary [user victor] right []'); + recordActivate(component: any): void { this.activations.push(component); } - // navigate back to a componentless route - router.navigateByUrl('/parent/11/(simple//right:user/victor)'); - advance(fixture); - expect(location.path()).toEqual('/parent/11/(simple//right:user/victor)'); - expect(fixture.nativeElement).toHaveText('primary [simple] right [user victor]'); - }))); + recordDeactivate(component: any): void { this.deactivations.push(component); } + } - it('should not deactivate aux routes when navigating from a componentless routes', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, TwoOutletsCmp); + TestBed.configureTestingModule({declarations: [Container]}); - router.resetConfig([ - {path: 'simple', component: SimpleCmp}, - {path: 'componentless', children: [{path: 'simple', component: SimpleCmp}]}, - {path: 'user/:name', outlet: 'aux', component: UserCmp} - ]); + const router: Router = TestBed.get(Router); - router.navigateByUrl('/componentless/simple(aux:user/victor)'); - advance(fixture); - expect(location.path()).toEqual('/componentless/simple(aux:user/victor)'); - expect(fixture.nativeElement).toHaveText('[ simple, aux: user victor ]'); + const fixture = createRoot(router, Container); + const cmp = fixture.componentInstance; - router.navigateByUrl('/simple(aux:user/victor)'); - advance(fixture); - expect(location.path()).toEqual('/simple(aux:user/victor)'); - expect(fixture.nativeElement).toHaveText('[ simple, aux: user victor ]'); - }))); + router.resetConfig( + [{path: 'blank', component: BlankCmp}, {path: 'simple', component: SimpleCmp}]); - it('should emit an event when an outlet gets activated', fakeAsync(() => { - @Component({ - selector: 'container', - template: - `` - }) - class Container { - activations: any[] = []; - deactivations: any[] = []; + cmp.activations = []; + cmp.deactivations = []; - recordActivate(component: any): void { this.activations.push(component); } + router.navigateByUrl('/blank'); + advance(fixture); - recordDeactivate(component: any): void { this.deactivations.push(component); } - } + expect(cmp.activations.length).toEqual(1); + expect(cmp.activations[0] instanceof BlankCmp).toBe(true); - TestBed.configureTestingModule({declarations: [Container]}); + router.navigateByUrl('/simple'); + advance(fixture); - const router: Router = TestBed.get(Router); + expect(cmp.activations.length).toEqual(2); + expect(cmp.activations[1] instanceof SimpleCmp).toBe(true); + expect(cmp.deactivations.length).toEqual(1); + expect(cmp.deactivations[0] instanceof BlankCmp).toBe(true); + })); - const fixture = createRoot(router, Container); - const cmp = fixture.componentInstance; + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should update url and router state before activating components', + fakeAsync(inject([Router], (router: Router) => { - router.resetConfig( - [{path: 'blank', component: BlankCmp}, {path: 'simple', component: SimpleCmp}]); + const fixture = createRoot(router, RootCmp); - cmp.activations = []; - cmp.deactivations = []; + router.resetConfig([{path: 'cmp', component: ComponentRecordingRoutePathAndUrl}]); - router.navigateByUrl('/blank'); - advance(fixture); + router.navigateByUrl('/cmp'); + advance(fixture); - expect(cmp.activations.length).toEqual(1); - expect(cmp.activations[0] instanceof BlankCmp).toBe(true); + const cmp = fixture.debugElement.children[1].componentInstance; - router.navigateByUrl('/simple'); - advance(fixture); - - expect(cmp.activations.length).toEqual(2); - expect(cmp.activations[1] instanceof SimpleCmp).toBe(true); - expect(cmp.deactivations.length).toEqual(1); - expect(cmp.deactivations[0] instanceof BlankCmp).toBe(true); - })); - - it('should update url and router state before activating components', - fakeAsync(inject([Router], (router: Router) => { - - const fixture = createRoot(router, RootCmp); - - router.resetConfig([{path: 'cmp', component: ComponentRecordingRoutePathAndUrl}]); - - router.navigateByUrl('/cmp'); - advance(fixture); - - const cmp = fixture.debugElement.children[1].componentInstance; - - expect(cmp.url).toBe('/cmp'); - expect(cmp.path.length).toEqual(2); - }))); + expect(cmp.url).toBe('/cmp'); + expect(cmp.path.length).toEqual(2); + }))); @@ -1315,45 +1345,47 @@ describe('Integration', () => { }); }); - it('should provide resolved data', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmpWithTwoOutlets); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should provide resolved data', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmpWithTwoOutlets); - router.resetConfig([{ - path: 'parent/:id', - data: {one: 1}, - resolve: {two: 'resolveTwo'}, - children: [ - {path: '', data: {three: 3}, resolve: {four: 'resolveFour'}, component: RouteCmp}, { - path: '', - data: {five: 5}, - resolve: {six: 'resolveSix'}, - component: RouteCmp, - outlet: 'right' - } - ] - }]); + router.resetConfig([{ + path: 'parent/:id', + data: {one: 1}, + resolve: {two: 'resolveTwo'}, + children: [ + {path: '', data: {three: 3}, resolve: {four: 'resolveFour'}, component: RouteCmp}, + { + path: '', + data: {five: 5}, + resolve: {six: 'resolveSix'}, + component: RouteCmp, + outlet: 'right' + } + ] + }]); - router.navigateByUrl('/parent/1'); - advance(fixture); + router.navigateByUrl('/parent/1'); + advance(fixture); - const primaryCmp = fixture.debugElement.children[1].componentInstance; - const rightCmp = fixture.debugElement.children[3].componentInstance; + const primaryCmp = fixture.debugElement.children[1].componentInstance; + const rightCmp = fixture.debugElement.children[3].componentInstance; - expect(primaryCmp.route.snapshot.data).toEqual({one: 1, two: 2, three: 3, four: 4}); - expect(rightCmp.route.snapshot.data).toEqual({one: 1, two: 2, five: 5, six: 6}); + expect(primaryCmp.route.snapshot.data).toEqual({one: 1, two: 2, three: 3, four: 4}); + expect(rightCmp.route.snapshot.data).toEqual({one: 1, two: 2, five: 5, six: 6}); - const primaryRecorded: any[] = []; - primaryCmp.route.data.forEach((rec: any) => primaryRecorded.push(rec)); + const primaryRecorded: any[] = []; + primaryCmp.route.data.forEach((rec: any) => primaryRecorded.push(rec)); - const rightRecorded: any[] = []; - rightCmp.route.data.forEach((rec: any) => rightRecorded.push(rec)); + const rightRecorded: any[] = []; + rightCmp.route.data.forEach((rec: any) => rightRecorded.push(rec)); - router.navigateByUrl('/parent/2'); - advance(fixture); + router.navigateByUrl('/parent/2'); + advance(fixture); - expect(primaryRecorded).toEqual([{one: 1, three: 3, two: 2, four: 4}]); - expect(rightRecorded).toEqual([{one: 1, five: 5, two: 2, six: 6}]); - }))); + expect(primaryRecorded).toEqual([{one: 1, three: 3, two: 2, four: 4}]); + expect(rightRecorded).toEqual([{one: 1, five: 5, two: 2, six: 6}]); + }))); it('should handle errors', fakeAsync(inject([Router], (router: Router) => { const fixture = createRoot(router, RootCmp); @@ -1393,50 +1425,52 @@ describe('Integration', () => { expect(e).toEqual(null); }))); - it('should preserve resolved data', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should preserve resolved data', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'parent', - resolve: {two: 'resolveTwo'}, - children: [ - {path: 'child1', component: CollectParamsCmp}, - {path: 'child2', component: CollectParamsCmp} - ] - }]); + router.resetConfig([{ + path: 'parent', + resolve: {two: 'resolveTwo'}, + children: [ + {path: 'child1', component: CollectParamsCmp}, + {path: 'child2', component: CollectParamsCmp} + ] + }]); - const e: any = null; - router.navigateByUrl('/parent/child1'); - advance(fixture); + const e: any = null; + router.navigateByUrl('/parent/child1'); + advance(fixture); - router.navigateByUrl('/parent/child2'); - advance(fixture); + router.navigateByUrl('/parent/child2'); + advance(fixture); - const cmp = fixture.debugElement.children[1].componentInstance; - expect(cmp.route.snapshot.data).toEqual({two: 2}); - }))); + const cmp = fixture.debugElement.children[1].componentInstance; + expect(cmp.route.snapshot.data).toEqual({two: 2}); + }))); - it('should rerun resolvers when the urls segments of a wildcard route change', - fakeAsync(inject([Router, Location], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should rerun resolvers when the urls segments of a wildcard route change', + fakeAsync(inject([Router, Location], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: '**', - component: CollectParamsCmp, - resolve: {numberOfUrlSegments: 'numberOfUrlSegments'} - }]); + router.resetConfig([{ + path: '**', + component: CollectParamsCmp, + resolve: {numberOfUrlSegments: 'numberOfUrlSegments'} + }]); - router.navigateByUrl('/one/two'); - advance(fixture); - const cmp = fixture.debugElement.children[1].componentInstance; + router.navigateByUrl('/one/two'); + advance(fixture); + const cmp = fixture.debugElement.children[1].componentInstance; - expect(cmp.route.snapshot.data).toEqual({numberOfUrlSegments: 2}); + expect(cmp.route.snapshot.data).toEqual({numberOfUrlSegments: 2}); - router.navigateByUrl('/one/two/three'); - advance(fixture); + router.navigateByUrl('/one/two/three'); + advance(fixture); - expect(cmp.route.snapshot.data).toEqual({numberOfUrlSegments: 3}); - }))); + expect(cmp.route.snapshot.data).toEqual({numberOfUrlSegments: 3}); + }))); describe('should run resolvers for the same route concurrently', () => { let log: string[]; @@ -1491,60 +1525,63 @@ describe('Integration', () => { }); describe('router links', () => { - it('should support skipping location update for anchor router links', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = TestBed.createComponent(RootCmp); - advance(fixture); + fixmeIvy('FW-???: ASSERTION ERROR: The provided value must be an instance of an HTMLElement') && + it('should support skipping location update for anchor router links', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = TestBed.createComponent(RootCmp); + advance(fixture); - router.resetConfig([{path: 'team/:id', component: TeamCmp}]); + router.resetConfig([{path: 'team/:id', component: TeamCmp}]); - router.navigateByUrl('/team/22'); - advance(fixture); - expect(location.path()).toEqual('/team/22'); - expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); + router.navigateByUrl('/team/22'); + advance(fixture); + expect(location.path()).toEqual('/team/22'); + expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]'); - const teamCmp = fixture.debugElement.childNodes[1].componentInstance; + const teamCmp = fixture.debugElement.childNodes[1].componentInstance; - teamCmp.routerLink = ['/team/0']; - advance(fixture); - const anchor = fixture.debugElement.query(By.css('a')).nativeElement; - anchor.click(); - advance(fixture); - expect(fixture.nativeElement).toHaveText('team 0 [ , right: ]'); - expect(location.path()).toEqual('/team/22'); + teamCmp.routerLink = ['/team/0']; + advance(fixture); + const anchor = fixture.debugElement.query(By.css('a')).nativeElement; + anchor.click(); + advance(fixture); + expect(fixture.nativeElement).toHaveText('team 0 [ , right: ]'); + expect(location.path()).toEqual('/team/22'); - teamCmp.routerLink = ['/team/1']; - advance(fixture); - const button = fixture.debugElement.query(By.css('button')).nativeElement; - button.click(); - advance(fixture); - expect(fixture.nativeElement).toHaveText('team 1 [ , right: ]'); - expect(location.path()).toEqual('/team/22'); - }))); + teamCmp.routerLink = ['/team/1']; + advance(fixture); + const button = fixture.debugElement.query(By.css('button')).nativeElement; + button.click(); + advance(fixture); + expect(fixture.nativeElement).toHaveText('team 1 [ , right: ]'); + expect(location.path()).toEqual('/team/22'); + }))); - it('should support string router links', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support string router links', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'link', component: StringLinkCmp}, {path: 'simple', component: SimpleCmp} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'link', component: StringLinkCmp}, + {path: 'simple', component: SimpleCmp} + ] + }]); - router.navigateByUrl('/team/22/link'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); + router.navigateByUrl('/team/22/link'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); - const native = fixture.nativeElement.querySelector('a'); - expect(native.getAttribute('href')).toEqual('/team/33/simple'); - expect(native.getAttribute('target')).toEqual('_self'); - native.click(); - advance(fixture); + const native = fixture.nativeElement.querySelector('a'); + expect(native.getAttribute('href')).toEqual('/team/33/simple'); + expect(native.getAttribute('target')).toEqual('_self'); + native.click(); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); - }))); + expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); + }))); it('should not preserve query params and fragment by default', fakeAsync(() => { @Component({ @@ -1662,126 +1699,134 @@ describe('Integration', () => { expect(native.getAttribute('href')).toEqual('/home?a=123&q=456'); })); - it('should support using links on non-a tags', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support using links on non-a tags', + fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'link', component: StringLinkButtonCmp}, - {path: 'simple', component: SimpleCmp} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'link', component: StringLinkButtonCmp}, + {path: 'simple', component: SimpleCmp} + ] + }]); - router.navigateByUrl('/team/22/link'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); + router.navigateByUrl('/team/22/link'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); - const button = fixture.nativeElement.querySelector('button'); - expect(button.getAttribute('tabindex')).toEqual('0'); - button.click(); - advance(fixture); + const button = fixture.nativeElement.querySelector('button'); + expect(button.getAttribute('tabindex')).toEqual('0'); + button.click(); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); - }))); + expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); + }))); - it('should support absolute router links', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support absolute router links', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'link', component: AbsoluteLinkCmp}, {path: 'simple', component: SimpleCmp} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'link', component: AbsoluteLinkCmp}, + {path: 'simple', component: SimpleCmp} + ] + }]); - router.navigateByUrl('/team/22/link'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); + router.navigateByUrl('/team/22/link'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); - const native = fixture.nativeElement.querySelector('a'); - expect(native.getAttribute('href')).toEqual('/team/33/simple'); - native.click(); - advance(fixture); + const native = fixture.nativeElement.querySelector('a'); + expect(native.getAttribute('href')).toEqual('/team/33/simple'); + native.click(); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); - }))); + expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); + }))); - it('should support relative router links', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support relative router links', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'link', component: RelativeLinkCmp}, {path: 'simple', component: SimpleCmp} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'link', component: RelativeLinkCmp}, + {path: 'simple', component: SimpleCmp} + ] + }]); - router.navigateByUrl('/team/22/link'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); + router.navigateByUrl('/team/22/link'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('team 22 [ link, right: ]'); - const native = fixture.nativeElement.querySelector('a'); - expect(native.getAttribute('href')).toEqual('/team/22/simple'); - native.click(); - advance(fixture); + const native = fixture.nativeElement.querySelector('a'); + expect(native.getAttribute('href')).toEqual('/team/22/simple'); + native.click(); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ simple, right: ]'); - }))); + expect(fixture.nativeElement).toHaveText('team 22 [ simple, right: ]'); + }))); - it('should support top-level link', fakeAsync(inject([Router], (router: Router) => { - const fixture = createRoot(router, RelativeLinkInIfCmp); - advance(fixture); + fixmeIvy('FW-662: Components without selector are not supported') && + it('should support top-level link', fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RelativeLinkInIfCmp); + advance(fixture); - router.resetConfig( - [{path: 'simple', component: SimpleCmp}, {path: '', component: BlankCmp}]); + router.resetConfig( + [{path: 'simple', component: SimpleCmp}, {path: '', component: BlankCmp}]); - router.navigateByUrl('/'); - advance(fixture); - expect(fixture.nativeElement).toHaveText(''); - const cmp = fixture.componentInstance; + router.navigateByUrl('/'); + advance(fixture); + expect(fixture.nativeElement).toHaveText(''); + const cmp = fixture.componentInstance; - cmp.show = true; - advance(fixture); + cmp.show = true; + advance(fixture); - expect(fixture.nativeElement).toHaveText('link'); - const native = fixture.nativeElement.querySelector('a'); + expect(fixture.nativeElement).toHaveText('link'); + const native = fixture.nativeElement.querySelector('a'); - expect(native.getAttribute('href')).toEqual('/simple'); - native.click(); - advance(fixture); + expect(native.getAttribute('href')).toEqual('/simple'); + native.click(); + advance(fixture); - expect(fixture.nativeElement).toHaveText('linksimple'); - }))); + expect(fixture.nativeElement).toHaveText('linksimple'); + }))); - it('should support query params and fragments', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support query params and fragments', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'link', component: LinkWithQueryParamsAndFragment}, - {path: 'simple', component: SimpleCmp} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'link', component: LinkWithQueryParamsAndFragment}, + {path: 'simple', component: SimpleCmp} + ] + }]); - router.navigateByUrl('/team/22/link'); - advance(fixture); + router.navigateByUrl('/team/22/link'); + advance(fixture); - const native = fixture.nativeElement.querySelector('a'); - expect(native.getAttribute('href')).toEqual('/team/22/simple?q=1#f'); - native.click(); - advance(fixture); + const native = fixture.nativeElement.querySelector('a'); + expect(native.getAttribute('href')).toEqual('/team/22/simple?q=1#f'); + native.click(); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ simple, right: ]'); + expect(fixture.nativeElement).toHaveText('team 22 [ simple, right: ]'); - expect(location.path()).toEqual('/team/22/simple?q=1#f'); - }))); + expect(location.path()).toEqual('/team/22/simple?q=1#f'); + }))); }); describe('redirects', () => { @@ -2035,21 +2080,23 @@ describe('Integration', () => { }] })); - it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - router.resetConfig([ - { - path: '', - component: SimpleCmp, - }, - {path: 'one', component: RouteCmp, canActivate: ['returnFalseAndNavigate']} - ]); + fixmeIvy('FW-???: assertion failures') && + it('works', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + router.resetConfig([ + { + path: '', + component: SimpleCmp, + }, + {path: 'one', component: RouteCmp, canActivate: ['returnFalseAndNavigate']} + ]); - const fixture = TestBed.createComponent(RootCmp); - router.navigateByUrl('/one'); - advance(fixture); - expect(location.path()).toEqual('/'); - expect(fixture.nativeElement).toHaveText('simple'); - }))); + const fixture = TestBed.createComponent(RootCmp); + router.navigateByUrl('/one'); + advance(fixture); + expect(location.path()).toEqual('/'); + expect(fixture.nativeElement).toHaveText('simple'); + }))); }); describe('should redirect when guard returns UrlTree', () => { @@ -2061,48 +2108,50 @@ describe('Integration', () => { }] })); - it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const recordedEvents: any[] = []; - let cancelEvent: NavigationCancel = null !; - router.events.forEach((e: any) => { - recordedEvents.push(e); - if (e instanceof NavigationCancel) cancelEvent = e; - }); - router.resetConfig([ - {path: '', component: SimpleCmp}, - {path: 'one', component: RouteCmp, canActivate: ['returnUrlTree']}, - {path: 'redirected', component: SimpleCmp} - ]); + fixmeIvy('FW-???: assertion failures') && + it('works', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const recordedEvents: any[] = []; + let cancelEvent: NavigationCancel = null !; + router.events.forEach((e: any) => { + recordedEvents.push(e); + if (e instanceof NavigationCancel) cancelEvent = e; + }); + router.resetConfig([ + {path: '', component: SimpleCmp}, + {path: 'one', component: RouteCmp, canActivate: ['returnUrlTree']}, + {path: 'redirected', component: SimpleCmp} + ]); - const fixture = TestBed.createComponent(RootCmp); - router.navigateByUrl('/one'); + const fixture = TestBed.createComponent(RootCmp); + router.navigateByUrl('/one'); - advance(fixture); + advance(fixture); - expect(location.path()).toEqual('/redirected'); - expect(fixture.nativeElement).toHaveText('simple'); - expect(cancelEvent && cancelEvent.reason) - .toBe('NavigationCancelingError: Redirecting to "/redirected"'); - expectEvents(recordedEvents, [ - [NavigationStart, '/one'], - [RoutesRecognized, '/one'], - [GuardsCheckStart, '/one'], - [ChildActivationStart, undefined], - [ActivationStart, undefined], - [NavigationCancel, '/one'], - [NavigationStart, '/redirected'], - [RoutesRecognized, '/redirected'], - [GuardsCheckStart, '/redirected'], - [ChildActivationStart, undefined], - [ActivationStart, undefined], - [GuardsCheckEnd, '/redirected'], - [ResolveStart, '/redirected'], - [ResolveEnd, '/redirected'], - [ActivationEnd, undefined], - [ChildActivationEnd, undefined], - [NavigationEnd, '/redirected'], - ]); - }))); + expect(location.path()).toEqual('/redirected'); + expect(fixture.nativeElement).toHaveText('simple'); + expect(cancelEvent && cancelEvent.reason) + .toBe('NavigationCancelingError: Redirecting to "/redirected"'); + expectEvents(recordedEvents, [ + [NavigationStart, '/one'], + [RoutesRecognized, '/one'], + [GuardsCheckStart, '/one'], + [ChildActivationStart, undefined], + [ActivationStart, undefined], + [NavigationCancel, '/one'], + [NavigationStart, '/redirected'], + [RoutesRecognized, '/redirected'], + [GuardsCheckStart, '/redirected'], + [ChildActivationStart, undefined], + [ActivationStart, undefined], + [GuardsCheckEnd, '/redirected'], + [ResolveStart, '/redirected'], + [ResolveEnd, '/redirected'], + [ActivationEnd, undefined], + [ChildActivationEnd, undefined], + [NavigationEnd, '/redirected'], + ]); + }))); }); describe('runGuardsAndResolvers', () => { @@ -2152,145 +2201,152 @@ describe('Integration', () => { return fixture; } - it('should rerun guards and resolvers when params change', - fakeAsync(inject([Router], (router: Router) => { - const fixture = configureRouter(router, 'paramsChange'); + fixmeIvy('FW-???: TypeError: Cannot read property \'data\' of undefined') && + it('should rerun guards and resolvers when params change', + fakeAsync(inject([Router], (router: Router) => { + const fixture = configureRouter(router, 'paramsChange'); - const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; - const recordedData: any[] = []; - cmp.route.data.subscribe((data: any) => recordedData.push(data)); + const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; + const recordedData: any[] = []; + cmp.route.data.subscribe((data: any) => recordedData.push(data)); - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - router.navigateByUrl('/a;p=1'); - advance(fixture); - expect(guardRunCount).toEqual(2); - expect(recordedData).toEqual([{data: 0}, {data: 1}]); + router.navigateByUrl('/a;p=1'); + advance(fixture); + expect(guardRunCount).toEqual(2); + expect(recordedData).toEqual([{data: 0}, {data: 1}]); - router.navigateByUrl('/a;p=2'); - advance(fixture); - expect(guardRunCount).toEqual(3); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); + router.navigateByUrl('/a;p=2'); + advance(fixture); + expect(guardRunCount).toEqual(3); + expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); - router.navigateByUrl('/a;p=2?q=1'); - advance(fixture); - expect(guardRunCount).toEqual(3); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); - }))); + router.navigateByUrl('/a;p=2?q=1'); + advance(fixture); + expect(guardRunCount).toEqual(3); + expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); + }))); - it('should rerun guards and resolvers when query params change', - fakeAsync(inject([Router], (router: Router) => { - const fixture = configureRouter(router, 'paramsOrQueryParamsChange'); + fixmeIvy('FW-???: TypeError: Cannot read property \'data\' of undefined') && + it('should rerun guards and resolvers when query params change', + fakeAsync(inject([Router], (router: Router) => { + const fixture = configureRouter(router, 'paramsOrQueryParamsChange'); - const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; - const recordedData: any[] = []; - cmp.route.data.subscribe((data: any) => recordedData.push(data)); + const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; + const recordedData: any[] = []; + cmp.route.data.subscribe((data: any) => recordedData.push(data)); - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - router.navigateByUrl('/a;p=1'); - advance(fixture); - expect(guardRunCount).toEqual(2); - expect(recordedData).toEqual([{data: 0}, {data: 1}]); + router.navigateByUrl('/a;p=1'); + advance(fixture); + expect(guardRunCount).toEqual(2); + expect(recordedData).toEqual([{data: 0}, {data: 1}]); - router.navigateByUrl('/a;p=2'); - advance(fixture); - expect(guardRunCount).toEqual(3); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); + router.navigateByUrl('/a;p=2'); + advance(fixture); + expect(guardRunCount).toEqual(3); + expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); - router.navigateByUrl('/a;p=2?q=1'); - advance(fixture); - expect(guardRunCount).toEqual(4); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]); + router.navigateByUrl('/a;p=2?q=1'); + advance(fixture); + expect(guardRunCount).toEqual(4); + expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]); - router.navigateByUrl('/a;p=2(right:b)?q=1'); - advance(fixture); - expect(guardRunCount).toEqual(4); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]); - }))); + router.navigateByUrl('/a;p=2(right:b)?q=1'); + advance(fixture); + expect(guardRunCount).toEqual(4); + expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]); + }))); - it('should always rerun guards and resolvers', - fakeAsync(inject([Router], (router: Router) => { - const fixture = configureRouter(router, 'always'); + fixmeIvy('FW-???: TypeError: Cannot read property \'data\' of undefined') && + it('should always rerun guards and resolvers', + fakeAsync(inject([Router], (router: Router) => { + const fixture = configureRouter(router, 'always'); - const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; - const recordedData: any[] = []; - cmp.route.data.subscribe((data: any) => recordedData.push(data)); + const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; + const recordedData: any[] = []; + cmp.route.data.subscribe((data: any) => recordedData.push(data)); - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - router.navigateByUrl('/a;p=1'); - advance(fixture); - expect(guardRunCount).toEqual(2); - expect(recordedData).toEqual([{data: 0}, {data: 1}]); + router.navigateByUrl('/a;p=1'); + advance(fixture); + expect(guardRunCount).toEqual(2); + expect(recordedData).toEqual([{data: 0}, {data: 1}]); - router.navigateByUrl('/a;p=2'); - advance(fixture); - expect(guardRunCount).toEqual(3); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); + router.navigateByUrl('/a;p=2'); + advance(fixture); + expect(guardRunCount).toEqual(3); + expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); - router.navigateByUrl('/a;p=2?q=1'); - advance(fixture); - expect(guardRunCount).toEqual(4); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]); + router.navigateByUrl('/a;p=2?q=1'); + advance(fixture); + expect(guardRunCount).toEqual(4); + expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]); - router.navigateByUrl('/a;p=2(right:b)?q=1'); - advance(fixture); - expect(guardRunCount).toEqual(5); - expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4}]); - }))); + router.navigateByUrl('/a;p=2(right:b)?q=1'); + advance(fixture); + expect(guardRunCount).toEqual(5); + expect(recordedData).toEqual([ + {data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4} + ]); + }))); - it('should not rerun guards and resolvers', fakeAsync(inject([Router], (router: Router) => { - const fixture = configureRouter(router, 'pathParamsChange'); + fixmeIvy('FW-???: TypeError: Cannot read property \'data\' of undefined') && + it('should not rerun guards and resolvers', + fakeAsync(inject([Router], (router: Router) => { + const fixture = configureRouter(router, 'pathParamsChange'); - const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; - const recordedData: any[] = []; - cmp.route.data.subscribe((data: any) => recordedData.push(data)); + const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; + const recordedData: any[] = []; + cmp.route.data.subscribe((data: any) => recordedData.push(data)); - // First navigation has already run - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + // First navigation has already run + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - // Changing any optional params will not result in running guards or resolvers - router.navigateByUrl('/a;p=1'); - advance(fixture); - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + // Changing any optional params will not result in running guards or resolvers + router.navigateByUrl('/a;p=1'); + advance(fixture); + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - router.navigateByUrl('/a;p=2'); - advance(fixture); - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + router.navigateByUrl('/a;p=2'); + advance(fixture); + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - router.navigateByUrl('/a;p=2?q=1'); - advance(fixture); - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + router.navigateByUrl('/a;p=2?q=1'); + advance(fixture); + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - router.navigateByUrl('/a;p=2(right:b)?q=1'); - advance(fixture); - expect(guardRunCount).toEqual(1); - expect(recordedData).toEqual([{data: 0}]); + router.navigateByUrl('/a;p=2(right:b)?q=1'); + advance(fixture); + expect(guardRunCount).toEqual(1); + expect(recordedData).toEqual([{data: 0}]); - // Change to new route with path param should run guards and resolvers - router.navigateByUrl('/c/paramValue'); - advance(fixture); + // Change to new route with path param should run guards and resolvers + router.navigateByUrl('/c/paramValue'); + advance(fixture); - expect(guardRunCount).toEqual(2); + expect(guardRunCount).toEqual(2); - // Modifying a path param should run guards and resolvers - router.navigateByUrl('/c/paramValueChanged'); - advance(fixture); - expect(guardRunCount).toEqual(3); + // Modifying a path param should run guards and resolvers + router.navigateByUrl('/c/paramValueChanged'); + advance(fixture); + expect(guardRunCount).toEqual(3); - // Adding optional params should not cause guards/resolvers to run - router.navigateByUrl('/c/paramValueChanged;p=1?q=2'); - advance(fixture); - expect(guardRunCount).toEqual(3); - }))); + // Adding optional params should not cause guards/resolvers to run + router.navigateByUrl('/c/paramValueChanged;p=1?q=2'); + advance(fixture); + expect(guardRunCount).toEqual(3); + }))); }); describe('should wait for parent to complete', () => { @@ -2415,68 +2471,72 @@ describe('Integration', () => { }); describe('should not deactivate a route when CanDeactivate returns false', () => { - it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('works', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig( - [{path: 'team/:id', component: TeamCmp, canDeactivate: ['CanDeactivateTeam']}]); + router.resetConfig([ + {path: 'team/:id', component: TeamCmp, canDeactivate: ['CanDeactivateTeam']} + ]); - router.navigateByUrl('/team/22'); - advance(fixture); - expect(location.path()).toEqual('/team/22'); + router.navigateByUrl('/team/22'); + advance(fixture); + expect(location.path()).toEqual('/team/22'); - let successStatus: boolean = false; - router.navigateByUrl('/team/33') !.then(res => successStatus = res); - advance(fixture); - expect(location.path()).toEqual('/team/33'); - expect(successStatus).toEqual(true); + let successStatus: boolean = false; + router.navigateByUrl('/team/33') !.then(res => successStatus = res); + advance(fixture); + expect(location.path()).toEqual('/team/33'); + expect(successStatus).toEqual(true); - let canceledStatus: boolean = false; - router.navigateByUrl('/team/44') !.then(res => canceledStatus = res); - advance(fixture); - expect(location.path()).toEqual('/team/33'); - expect(canceledStatus).toEqual(false); - }))); + let canceledStatus: boolean = false; + router.navigateByUrl('/team/44') !.then(res => canceledStatus = res); + advance(fixture); + expect(location.path()).toEqual('/team/33'); + expect(canceledStatus).toEqual(false); + }))); - it('works with componentless routes', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('works with componentless routes', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - { - path: 'grandparent', - canDeactivate: ['RecordingDeactivate'], - children: [{ - path: 'parent', - canDeactivate: ['RecordingDeactivate'], - children: [{ - path: 'child', + router.resetConfig([ + { + path: 'grandparent', canDeactivate: ['RecordingDeactivate'], children: [{ - path: 'simple', - component: SimpleCmp, - canDeactivate: ['RecordingDeactivate'] + path: 'parent', + canDeactivate: ['RecordingDeactivate'], + children: [{ + path: 'child', + canDeactivate: ['RecordingDeactivate'], + children: [{ + path: 'simple', + component: SimpleCmp, + canDeactivate: ['RecordingDeactivate'] + }] + }] }] - }] - }] - }, - {path: 'simple', component: SimpleCmp} - ]); + }, + {path: 'simple', component: SimpleCmp} + ]); - router.navigateByUrl('/grandparent/parent/child/simple'); - advance(fixture); - expect(location.path()).toEqual('/grandparent/parent/child/simple'); + router.navigateByUrl('/grandparent/parent/child/simple'); + advance(fixture); + expect(location.path()).toEqual('/grandparent/parent/child/simple'); - router.navigateByUrl('/simple'); - advance(fixture); + router.navigateByUrl('/simple'); + advance(fixture); - const child = fixture.debugElement.children[1].componentInstance; + const child = fixture.debugElement.children[1].componentInstance; - expect(log.map((a: any) => a.path)).toEqual([ - 'simple', 'child', 'parent', 'grandparent' - ]); - expect(log.map((a: any) => a.component)).toEqual([child, null, null, null]); - }))); + expect(log.map((a: any) => a.path)).toEqual([ + 'simple', 'child', 'parent', 'grandparent' + ]); + expect(log.map((a: any) => a.component)).toEqual([child, null, null, null]); + }))); it('works with aux routes', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { @@ -2506,60 +2566,65 @@ describe('Integration', () => { expect(location.path()).toEqual('/two-outlets/(a)'); }))); - it('works with a nested route', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('works with a nested route', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: '', pathMatch: 'full', component: SimpleCmp}, - {path: 'user/:name', component: UserCmp, canDeactivate: ['CanDeactivateUser']} - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: '', pathMatch: 'full', component: SimpleCmp}, { + path: 'user/:name', + component: UserCmp, + canDeactivate: ['CanDeactivateUser'] + } + ] + }]); - router.navigateByUrl('/team/22/user/victor'); - advance(fixture); + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); - // this works because we can deactivate victor - router.navigateByUrl('/team/33'); - advance(fixture); - expect(location.path()).toEqual('/team/33'); + // this works because we can deactivate victor + router.navigateByUrl('/team/33'); + advance(fixture); + expect(location.path()).toEqual('/team/33'); - router.navigateByUrl('/team/33/user/fedor'); - advance(fixture); + router.navigateByUrl('/team/33/user/fedor'); + advance(fixture); - // this doesn't work cause we cannot deactivate fedor - router.navigateByUrl('/team/44'); - advance(fixture); - expect(location.path()).toEqual('/team/33/user/fedor'); - }))); + // this doesn't work cause we cannot deactivate fedor + router.navigateByUrl('/team/44'); + advance(fixture); + expect(location.path()).toEqual('/team/33/user/fedor'); + }))); }); - it('should not create a route state if navigation is canceled', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') && + it('should not create a route state if navigation is canceled', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'main', - component: TeamCmp, - children: [ - {path: 'component1', component: SimpleCmp, canDeactivate: ['alwaysFalse']}, - {path: 'component2', component: SimpleCmp} - ] - }]); + router.resetConfig([{ + path: 'main', + component: TeamCmp, + children: [ + {path: 'component1', component: SimpleCmp, canDeactivate: ['alwaysFalse']}, + {path: 'component2', component: SimpleCmp} + ] + }]); - router.navigateByUrl('/main/component1'); - advance(fixture); + router.navigateByUrl('/main/component1'); + advance(fixture); - router.navigateByUrl('/main/component2'); - advance(fixture); + router.navigateByUrl('/main/component2'); + advance(fixture); - const teamCmp = fixture.debugElement.children[1].componentInstance; - expect(teamCmp.route.firstChild.url.value[0].path).toEqual('component1'); - expect(location.path()).toEqual('/main/component1'); - }))); + const teamCmp = fixture.debugElement.children[1].componentInstance; + expect(teamCmp.route.firstChild.url.value[0].path).toEqual('component1'); + expect(location.path()).toEqual('/main/component1'); + }))); it('should not run CanActivate when CanDeactivate returns false', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { @@ -2644,40 +2709,44 @@ describe('Integration', () => { }); }); - it('should pass next state as the 4 argument when guard is a class', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should pass next state as the 4 argument when guard is a class', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig( - [{path: 'team/:id', component: TeamCmp, canDeactivate: [ClassWithNextState]}]); + router.resetConfig( + [{path: 'team/:id', component: TeamCmp, canDeactivate: [ClassWithNextState]}]); - router.navigateByUrl('/team/22'); - advance(fixture); - expect(location.path()).toEqual('/team/22'); + router.navigateByUrl('/team/22'); + advance(fixture); + expect(location.path()).toEqual('/team/22'); - router.navigateByUrl('/team/33'); - advance(fixture); - expect(location.path()).toEqual('/team/33'); - expect(log).toEqual(['/team/22', '/team/33']); - }))); + router.navigateByUrl('/team/33'); + advance(fixture); + expect(location.path()).toEqual('/team/33'); + expect(log).toEqual(['/team/22', '/team/33']); + }))); - it('should pass next state as the 4 argument when guard is a function', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should pass next state as the 4 argument when guard is a function', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - {path: 'team/:id', component: TeamCmp, canDeactivate: ['FunctionWithNextState']} - ]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + canDeactivate: ['FunctionWithNextState'] + }]); - router.navigateByUrl('/team/22'); - advance(fixture); - expect(location.path()).toEqual('/team/22'); + router.navigateByUrl('/team/22'); + advance(fixture); + expect(location.path()).toEqual('/team/22'); - router.navigateByUrl('/team/33'); - advance(fixture); - expect(location.path()).toEqual('/team/33'); - expect(log).toEqual(['/team/22', '/team/33']); - }))); + router.navigateByUrl('/team/33'); + advance(fixture); + expect(location.path()).toEqual('/team/33'); + expect(log).toEqual(['/team/22', '/team/33']); + }))); }); describe('should work when given a class', () => { @@ -2691,20 +2760,22 @@ describe('Integration', () => { beforeEach(() => { TestBed.configureTestingModule({providers: [AlwaysTrue]}); }); - it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('works', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig( - [{path: 'team/:id', component: TeamCmp, canDeactivate: [AlwaysTrue]}]); + router.resetConfig( + [{path: 'team/:id', component: TeamCmp, canDeactivate: [AlwaysTrue]}]); - router.navigateByUrl('/team/22'); - advance(fixture); - expect(location.path()).toEqual('/team/22'); + router.navigateByUrl('/team/22'); + advance(fixture); + expect(location.path()).toEqual('/team/22'); - router.navigateByUrl('/team/33'); - advance(fixture); - expect(location.path()).toEqual('/team/33'); - }))); + router.navigateByUrl('/team/33'); + advance(fixture); + expect(location.path()).toEqual('/team/33'); + }))); }); @@ -2769,46 +2840,47 @@ describe('Integration', () => { }))); }); - it('should find the guard provided in lazy loaded module', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should find the guard provided in lazy loaded module', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'admin', template: ''}) - class AdminComponent { - } + @Component({selector: 'admin', template: ''}) + class AdminComponent { + } - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyLoadedComponent { - } + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [AdminComponent, LazyLoadedComponent], - imports: [RouterModule.forChild([{ - path: '', - component: AdminComponent, - children: [{ - path: '', - canActivateChild: ['alwaysTrue'], - children: [{path: '', component: LazyLoadedComponent}] - }] - }])], - providers: [{provide: 'alwaysTrue', useValue: () => true}], - }) - class LazyLoadedModule { - } + @NgModule({ + declarations: [AdminComponent, LazyLoadedComponent], + imports: [RouterModule.forChild([{ + path: '', + component: AdminComponent, + children: [{ + path: '', + canActivateChild: ['alwaysTrue'], + children: [{path: '', component: LazyLoadedComponent}] + }] + }])], + providers: [{provide: 'alwaysTrue', useValue: () => true}], + }) + class LazyLoadedModule { + } - loader.stubbedModules = {lazy: LazyLoadedModule}; - const fixture = createRoot(router, RootCmp); + loader.stubbedModules = {lazy: LazyLoadedModule}; + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'admin', loadChildren: 'lazy'}]); + router.resetConfig([{path: 'admin', loadChildren: 'lazy'}]); - router.navigateByUrl('/admin'); - advance(fixture); + router.navigateByUrl('/admin'); + advance(fixture); - expect(location.path()).toEqual('/admin'); - expect(fixture.nativeElement).toHaveText('lazy-loaded'); - }))); + expect(location.path()).toEqual('/admin'); + expect(fixture.nativeElement).toHaveText('lazy-loaded'); + }))); }); describe('CanLoad', () => { @@ -2837,75 +2909,76 @@ describe('Integration', () => { }); }); - it('should not load children when CanLoad returns false', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not load children when CanLoad returns false', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyLoadedComponent { - } + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: - [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])] - }) - class LoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: [RouterModule.forChild( + [{path: 'loaded', component: LazyLoadedComponent}])] + }) + class LoadedModule { + } - loader.stubbedModules = {lazyFalse: LoadedModule, lazyTrue: LoadedModule}; - const fixture = createRoot(router, RootCmp); + loader.stubbedModules = {lazyFalse: LoadedModule, lazyTrue: LoadedModule}; + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - {path: 'lazyFalse', canLoad: ['alwaysFalse'], loadChildren: 'lazyFalse'}, - {path: 'lazyTrue', canLoad: ['alwaysTrue'], loadChildren: 'lazyTrue'} - ]); + router.resetConfig([ + {path: 'lazyFalse', canLoad: ['alwaysFalse'], loadChildren: 'lazyFalse'}, + {path: 'lazyTrue', canLoad: ['alwaysTrue'], loadChildren: 'lazyTrue'} + ]); - const recordedEvents: any[] = []; - router.events.forEach(e => recordedEvents.push(e)); + const recordedEvents: any[] = []; + router.events.forEach(e => recordedEvents.push(e)); - // failed navigation - router.navigateByUrl('/lazyFalse/loaded'); - advance(fixture); + // failed navigation + router.navigateByUrl('/lazyFalse/loaded'); + advance(fixture); - expect(location.path()).toEqual('/'); + expect(location.path()).toEqual('/'); - expectEvents(recordedEvents, [ - [NavigationStart, '/lazyFalse/loaded'], - // [GuardsCheckStart, '/lazyFalse/loaded'], - [NavigationCancel, '/lazyFalse/loaded'], - ]); + expectEvents(recordedEvents, [ + [NavigationStart, '/lazyFalse/loaded'], + // [GuardsCheckStart, '/lazyFalse/loaded'], + [NavigationCancel, '/lazyFalse/loaded'], + ]); - recordedEvents.splice(0); + recordedEvents.splice(0); - // successful navigation - router.navigateByUrl('/lazyTrue/loaded'); - advance(fixture); + // successful navigation + router.navigateByUrl('/lazyTrue/loaded'); + advance(fixture); - expect(location.path()).toEqual('/lazyTrue/loaded'); + expect(location.path()).toEqual('/lazyTrue/loaded'); - expectEvents(recordedEvents, [ - [NavigationStart, '/lazyTrue/loaded'], - [RouteConfigLoadStart], - [RouteConfigLoadEnd], - [RoutesRecognized, '/lazyTrue/loaded'], - [GuardsCheckStart, '/lazyTrue/loaded'], - [ChildActivationStart], - [ActivationStart], - [ChildActivationStart], - [ActivationStart], - [GuardsCheckEnd, '/lazyTrue/loaded'], - [ResolveStart, '/lazyTrue/loaded'], - [ResolveEnd, '/lazyTrue/loaded'], - [ActivationEnd], - [ChildActivationEnd], - [ActivationEnd], - [ChildActivationEnd], - [NavigationEnd, '/lazyTrue/loaded'], - ]); - }))); + expectEvents(recordedEvents, [ + [NavigationStart, '/lazyTrue/loaded'], + [RouteConfigLoadStart], + [RouteConfigLoadEnd], + [RoutesRecognized, '/lazyTrue/loaded'], + [GuardsCheckStart, '/lazyTrue/loaded'], + [ChildActivationStart], + [ActivationStart], + [ChildActivationStart], + [ActivationStart], + [GuardsCheckEnd, '/lazyTrue/loaded'], + [ResolveStart, '/lazyTrue/loaded'], + [ResolveEnd, '/lazyTrue/loaded'], + [ActivationEnd], + [ChildActivationEnd], + [ActivationEnd], + [ChildActivationEnd], + [NavigationEnd, '/lazyTrue/loaded'], + ]); + }))); it('should support navigating from within the guard', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { @@ -2941,79 +3014,82 @@ describe('Integration', () => { // Regression where navigateByUrl with false CanLoad no longer resolved `false` value on // navigateByUrl promise: https://github.com/angular/angular/issues/26284 - it('should resolve navigateByUrl promise after CanLoad executes', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should resolve navigateByUrl promise after CanLoad executes', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyLoadedComponent { - } + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: - [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])] - }) - class LazyLoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: [RouterModule.forChild( + [{path: 'loaded', component: LazyLoadedComponent}])] + }) + class LazyLoadedModule { + } - loader.stubbedModules = {lazy: LazyLoadedModule}; - const fixture = createRoot(router, RootCmp); + loader.stubbedModules = {lazy: LazyLoadedModule}; + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - {path: 'lazy-false', canLoad: ['alwaysFalse'], loadChildren: 'lazy'}, - {path: 'lazy-true', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}, - ]); + router.resetConfig([ + {path: 'lazy-false', canLoad: ['alwaysFalse'], loadChildren: 'lazy'}, + {path: 'lazy-true', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}, + ]); - let navFalseResult: any; - let navTrueResult: any; - router.navigateByUrl('/lazy-false').then(v => { navFalseResult = v; }); - advance(fixture); - router.navigateByUrl('/lazy-true').then(v => { navTrueResult = v; }); - advance(fixture); + let navFalseResult: any; + let navTrueResult: any; + router.navigateByUrl('/lazy-false').then(v => { navFalseResult = v; }); + advance(fixture); + router.navigateByUrl('/lazy-true').then(v => { navTrueResult = v; }); + advance(fixture); - expect(navFalseResult).toBe(false); - expect(navTrueResult).toBe(true); + expect(navFalseResult).toBe(false); + expect(navTrueResult).toBe(true); - }))); + }))); - it('should execute CanLoad only once', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should execute CanLoad only once', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyLoadedComponent { - } + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: - [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])] - }) - class LazyLoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: [RouterModule.forChild( + [{path: 'loaded', component: LazyLoadedComponent}])] + }) + class LazyLoadedModule { + } - loader.stubbedModules = {lazy: LazyLoadedModule}; - const fixture = createRoot(router, RootCmp); + loader.stubbedModules = {lazy: LazyLoadedModule}; + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}]); + router.resetConfig( + [{path: 'lazy', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}]); - router.navigateByUrl('/lazy/loaded'); - advance(fixture); - expect(location.path()).toEqual('/lazy/loaded'); - expect(canLoadRunCount).toEqual(1); + router.navigateByUrl('/lazy/loaded'); + advance(fixture); + expect(location.path()).toEqual('/lazy/loaded'); + expect(canLoadRunCount).toEqual(1); - router.navigateByUrl('/'); - advance(fixture); - expect(location.path()).toEqual('/'); + router.navigateByUrl('/'); + advance(fixture); + expect(location.path()).toEqual('/'); - router.navigateByUrl('/lazy/loaded'); - advance(fixture); - expect(location.path()).toEqual('/lazy/loaded'); - expect(canLoadRunCount).toEqual(1); - }))); + router.navigateByUrl('/lazy/loaded'); + advance(fixture); + expect(location.path()).toEqual('/lazy/loaded'); + expect(canLoadRunCount).toEqual(1); + }))); }); describe('order', () => { @@ -3050,59 +3126,64 @@ describe('Integration', () => { }); }); - it('should call guards in the right order', - fakeAsync(inject( - [Router, Location, Logger], (router: Router, location: Location, logger: Logger) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should call guards in the right order', + fakeAsync(inject( + [Router, Location, Logger], + (router: Router, location: Location, logger: Logger) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: '', - canActivateChild: ['canActivateChild_parent'], - children: [{ - path: 'team/:id', - canActivate: ['canActivate_team'], - canDeactivate: ['canDeactivate_team'], - component: TeamCmp - }] - }]); + router.resetConfig([{ + path: '', + canActivateChild: ['canActivateChild_parent'], + children: [{ + path: 'team/:id', + canActivate: ['canActivate_team'], + canDeactivate: ['canDeactivate_team'], + component: TeamCmp + }] + }]); - router.navigateByUrl('/team/22'); - advance(fixture); + router.navigateByUrl('/team/22'); + advance(fixture); - router.navigateByUrl('/team/33'); - advance(fixture); + router.navigateByUrl('/team/33'); + advance(fixture); - expect(logger.logs).toEqual([ - 'canActivateChild_parent', 'canActivate_team', + expect(logger.logs).toEqual([ + 'canActivateChild_parent', 'canActivate_team', - 'canDeactivate_team', 'canActivateChild_parent', 'canActivate_team' - ]); - }))); + 'canDeactivate_team', 'canActivateChild_parent', 'canActivate_team' + ]); + }))); - it('should call deactivate guards from bottom to top', - fakeAsync(inject( - [Router, Location, Logger], (router: Router, location: Location, logger: Logger) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') && + it('should call deactivate guards from bottom to top', + fakeAsync(inject( + [Router, Location, Logger], + (router: Router, location: Location, logger: Logger) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: '', - children: [{ - path: 'team/:id', - canDeactivate: ['canDeactivate_team'], - children: - [{path: '', component: SimpleCmp, canDeactivate: ['canDeactivate_simple']}], - component: TeamCmp - }] - }]); + router.resetConfig([{ + path: '', + children: [{ + path: 'team/:id', + canDeactivate: ['canDeactivate_team'], + children: [ + {path: '', component: SimpleCmp, canDeactivate: ['canDeactivate_simple']} + ], + component: TeamCmp + }] + }]); - router.navigateByUrl('/team/22'); - advance(fixture); + router.navigateByUrl('/team/22'); + advance(fixture); - router.navigateByUrl('/team/33'); - advance(fixture); + router.navigateByUrl('/team/33'); + advance(fixture); - expect(logger.logs).toEqual(['canDeactivate_simple', 'canDeactivate_team']); - }))); + expect(logger.logs).toEqual(['canDeactivate_simple', 'canDeactivate_team']); + }))); }); }); @@ -3285,48 +3366,49 @@ describe('Integration', () => { }))); - it('should expose an isActive property', fakeAsync(() => { - @Component({ - template: ` + fixmeIvy('FW-662: Components without selector are not supported') && + it('should expose an isActive property', fakeAsync(() => { + @Component({ + template: `

{{rla.isActive}}

` - }) - class ComponentWithRouterLink { - } + }) + class ComponentWithRouterLink { + } - TestBed.configureTestingModule({declarations: [ComponentWithRouterLink]}); - const router: Router = TestBed.get(Router); + TestBed.configureTestingModule({declarations: [ComponentWithRouterLink]}); + const router: Router = TestBed.get(Router); - router.resetConfig([ - { - path: 'team', - component: TeamCmp, - }, - { - path: 'otherteam', - component: TeamCmp, - } - ]); + router.resetConfig([ + { + path: 'team', + component: TeamCmp, + }, + { + path: 'otherteam', + component: TeamCmp, + } + ]); - const fixture = TestBed.createComponent(ComponentWithRouterLink); - router.navigateByUrl('/team'); - expect(() => advance(fixture)).not.toThrow(); - advance(fixture); + const fixture = TestBed.createComponent(ComponentWithRouterLink); + router.navigateByUrl('/team'); + expect(() => advance(fixture)).not.toThrow(); + advance(fixture); - const paragraph = fixture.nativeElement.querySelector('p'); - expect(paragraph.textContent).toEqual('true'); + const paragraph = fixture.nativeElement.querySelector('p'); + expect(paragraph.textContent).toEqual('true'); - router.navigateByUrl('/otherteam'); - advance(fixture); - advance(fixture); - expect(paragraph.textContent).toEqual('false'); - })); + router.navigateByUrl('/otherteam'); + advance(fixture); + advance(fixture); + expect(paragraph.textContent).toEqual('false'); + })); }); - describe('lazy loading', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && describe('lazy loading', () => { it('works', fakeAsync(inject( [Router, Location, NgModuleFactoryLoader], @@ -3367,345 +3449,358 @@ describe('Integration', () => { expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); }))); - it('should have 2 injector trees: module and element', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({ - selector: 'lazy', - template: 'parent[]', - viewProviders: [ - {provide: 'shadow', useValue: 'from parent component'}, - ], - }) - class Parent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should have 2 injector trees: module and element', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({ + selector: 'lazy', + template: 'parent[]', + viewProviders: [ + {provide: 'shadow', useValue: 'from parent component'}, + ], + }) + class Parent { + } - @Component({selector: 'lazy', template: 'child'}) - class Child { - } + @Component({selector: 'lazy', template: 'child'}) + class Child { + } - @NgModule({ - declarations: [Parent], - imports: [RouterModule.forChild([{ - path: 'parent', - component: Parent, - children: [ - {path: 'child', loadChildren: 'child'}, - ] - }])], - providers: [ - {provide: 'moduleName', useValue: 'parent'}, - {provide: 'fromParent', useValue: 'from parent'}, - ], - }) - class ParentModule { - } + @NgModule({ + declarations: [Parent], + imports: [RouterModule.forChild([{ + path: 'parent', + component: Parent, + children: [ + {path: 'child', loadChildren: 'child'}, + ] + }])], + providers: [ + {provide: 'moduleName', useValue: 'parent'}, + {provide: 'fromParent', useValue: 'from parent'}, + ], + }) + class ParentModule { + } - @NgModule({ - declarations: [Child], - imports: [RouterModule.forChild([{path: '', component: Child}])], - providers: [ - {provide: 'moduleName', useValue: 'child'}, - {provide: 'fromChild', useValue: 'from child'}, - {provide: 'shadow', useValue: 'from child module'}, - ], - }) - class ChildModule { - } + @NgModule({ + declarations: [Child], + imports: [RouterModule.forChild([{path: '', component: Child}])], + providers: [ + {provide: 'moduleName', useValue: 'child'}, + {provide: 'fromChild', useValue: 'from child'}, + {provide: 'shadow', useValue: 'from child module'}, + ], + }) + class ChildModule { + } - loader.stubbedModules = { - parent: ParentModule, - child: ChildModule, - }; + loader.stubbedModules = { + parent: ParentModule, + child: ChildModule, + }; - const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'parent'}]); - router.navigateByUrl('/lazy/parent/child'); - advance(fixture); - expect(location.path()).toEqual('/lazy/parent/child'); - expect(fixture.nativeElement).toHaveText('parent[child]'); + const fixture = createRoot(router, RootCmp); + router.resetConfig([{path: 'lazy', loadChildren: 'parent'}]); + router.navigateByUrl('/lazy/parent/child'); + advance(fixture); + expect(location.path()).toEqual('/lazy/parent/child'); + expect(fixture.nativeElement).toHaveText('parent[child]'); - const pInj = fixture.debugElement.query(By.directive(Parent)).injector !; - const cInj = fixture.debugElement.query(By.directive(Child)).injector !; + const pInj = fixture.debugElement.query(By.directive(Parent)).injector !; + const cInj = fixture.debugElement.query(By.directive(Child)).injector !; - expect(pInj.get('moduleName')).toEqual('parent'); - expect(pInj.get('fromParent')).toEqual('from parent'); - expect(pInj.get(Parent)).toBeAnInstanceOf(Parent); - expect(pInj.get('fromChild', null)).toEqual(null); - expect(pInj.get(Child, null)).toEqual(null); + expect(pInj.get('moduleName')).toEqual('parent'); + expect(pInj.get('fromParent')).toEqual('from parent'); + expect(pInj.get(Parent)).toBeAnInstanceOf(Parent); + expect(pInj.get('fromChild', null)).toEqual(null); + expect(pInj.get(Child, null)).toEqual(null); - expect(cInj.get('moduleName')).toEqual('child'); - expect(cInj.get('fromParent')).toEqual('from parent'); - expect(cInj.get('fromChild')).toEqual('from child'); - expect(cInj.get(Parent)).toBeAnInstanceOf(Parent); - expect(cInj.get(Child)).toBeAnInstanceOf(Child); - // The child module can not shadow the parent component - expect(cInj.get('shadow')).toEqual('from parent component'); + expect(cInj.get('moduleName')).toEqual('child'); + expect(cInj.get('fromParent')).toEqual('from parent'); + expect(cInj.get('fromChild')).toEqual('from child'); + expect(cInj.get(Parent)).toBeAnInstanceOf(Parent); + expect(cInj.get(Child)).toBeAnInstanceOf(Child); + // The child module can not shadow the parent component + expect(cInj.get('shadow')).toEqual('from parent component'); - const pmInj = pInj.get(NgModuleRef).injector; - const cmInj = cInj.get(NgModuleRef).injector; + const pmInj = pInj.get(NgModuleRef).injector; + const cmInj = cInj.get(NgModuleRef).injector; - expect(pmInj.get('moduleName')).toEqual('parent'); - expect(cmInj.get('moduleName')).toEqual('child'); + expect(pmInj.get('moduleName')).toEqual('parent'); + expect(cmInj.get('moduleName')).toEqual('child'); - expect(pmInj.get(Parent, '-')).toEqual('-'); - expect(cmInj.get(Parent, '-')).toEqual('-'); - expect(pmInj.get(Child, '-')).toEqual('-'); - expect(cmInj.get(Child, '-')).toEqual('-'); - }))); + expect(pmInj.get(Parent, '-')).toEqual('-'); + expect(cmInj.get(Parent, '-')).toEqual('-'); + expect(pmInj.get(Child, '-')).toEqual('-'); + expect(cmInj.get(Child, '-')).toEqual('-'); + }))); // https://github.com/angular/angular/issues/12889 - it('should create a single instance of lazy-loaded modules', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({ - selector: 'lazy', - template: 'lazy-loaded-parent []' - }) - class ParentLazyLoadedComponent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create a single instance of lazy-loaded modules', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({ + selector: 'lazy', + template: 'lazy-loaded-parent []' + }) + class ParentLazyLoadedComponent { + } - @Component({selector: 'lazy', template: 'lazy-loaded-child'}) - class ChildLazyLoadedComponent { - } + @Component({selector: 'lazy', template: 'lazy-loaded-child'}) + class ChildLazyLoadedComponent { + } - @NgModule({ - declarations: [ParentLazyLoadedComponent, ChildLazyLoadedComponent], - imports: [RouterModule.forChild([{ - path: 'loaded', - component: ParentLazyLoadedComponent, - children: [{path: 'child', component: ChildLazyLoadedComponent}] - }])] - }) - class LoadedModule { - static instances = 0; - constructor() { LoadedModule.instances++; } - } + @NgModule({ + declarations: [ParentLazyLoadedComponent, ChildLazyLoadedComponent], + imports: [RouterModule.forChild([{ + path: 'loaded', + component: ParentLazyLoadedComponent, + children: [{path: 'child', component: ChildLazyLoadedComponent}] + }])] + }) + class LoadedModule { + static instances = 0; + constructor() { LoadedModule.instances++; } + } - loader.stubbedModules = {expected: LoadedModule}; - const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); - router.navigateByUrl('/lazy/loaded/child'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); - expect(LoadedModule.instances).toEqual(1); - }))); + loader.stubbedModules = {expected: LoadedModule}; + const fixture = createRoot(router, RootCmp); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + router.navigateByUrl('/lazy/loaded/child'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); + expect(LoadedModule.instances).toEqual(1); + }))); // https://github.com/angular/angular/issues/13870 - it('should create a single instance of guards for lazy-loaded modules', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Injectable() - class Service { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create a single instance of guards for lazy-loaded modules', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Injectable() + class Service { + } - @Injectable() - class Resolver implements Resolve { - constructor(public service: Service) {} - resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { - return this.service; - } - } + @Injectable() + class Resolver implements Resolve { + constructor(public service: Service) {} + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + return this.service; + } + } - @Component({selector: 'lazy', template: 'lazy'}) - class LazyLoadedComponent { - resolvedService: Service; - constructor(public injectedService: Service, route: ActivatedRoute) { - this.resolvedService = route.snapshot.data['service']; - } - } + @Component({selector: 'lazy', template: 'lazy'}) + class LazyLoadedComponent { + resolvedService: Service; + constructor(public injectedService: Service, route: ActivatedRoute) { + this.resolvedService = route.snapshot.data['service']; + } + } - @NgModule({ - declarations: [LazyLoadedComponent], - providers: [Service, Resolver], - imports: [ - RouterModule.forChild([{ - path: 'loaded', - component: LazyLoadedComponent, - resolve: {'service': Resolver}, - }]), - ] - }) - class LoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + providers: [Service, Resolver], + imports: [ + RouterModule.forChild([{ + path: 'loaded', + component: LazyLoadedComponent, + resolve: {'service': Resolver}, + }]), + ] + }) + class LoadedModule { + } - loader.stubbedModules = {expected: LoadedModule}; - const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); - router.navigateByUrl('/lazy/loaded'); - advance(fixture); + loader.stubbedModules = {expected: LoadedModule}; + const fixture = createRoot(router, RootCmp); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + router.navigateByUrl('/lazy/loaded'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('lazy'); - const lzc = - fixture.debugElement.query(By.directive(LazyLoadedComponent)).componentInstance; - expect(lzc.injectedService).toBe(lzc.resolvedService); - }))); + expect(fixture.nativeElement).toHaveText('lazy'); + const lzc = fixture.debugElement.query(By.directive(LazyLoadedComponent)) + .componentInstance; + expect(lzc.injectedService).toBe(lzc.resolvedService); + }))); - it('should emit RouteConfigLoadStart and RouteConfigLoadEnd event when route is lazy loaded', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({ - selector: 'lazy', - template: 'lazy-loaded-parent []', - }) - class ParentLazyLoadedComponent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should emit RouteConfigLoadStart and RouteConfigLoadEnd event when route is lazy loaded', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({ + selector: 'lazy', + template: 'lazy-loaded-parent []', + }) + class ParentLazyLoadedComponent { + } - @Component({selector: 'lazy', template: 'lazy-loaded-child'}) - class ChildLazyLoadedComponent { - } + @Component({selector: 'lazy', template: 'lazy-loaded-child'}) + class ChildLazyLoadedComponent { + } - @NgModule({ - declarations: [ParentLazyLoadedComponent, ChildLazyLoadedComponent], - imports: [RouterModule.forChild([{ - path: 'loaded', - component: ParentLazyLoadedComponent, - children: [{path: 'child', component: ChildLazyLoadedComponent}], - }])] - }) - class LoadedModule { - } + @NgModule({ + declarations: [ParentLazyLoadedComponent, ChildLazyLoadedComponent], + imports: [RouterModule.forChild([{ + path: 'loaded', + component: ParentLazyLoadedComponent, + children: [{path: 'child', component: ChildLazyLoadedComponent}], + }])] + }) + class LoadedModule { + } - const events: Array = []; + const events: Array = []; - router.events.subscribe(e => { - if (e instanceof RouteConfigLoadStart || e instanceof RouteConfigLoadEnd) { - events.push(e); - } - }); + router.events.subscribe(e => { + if (e instanceof RouteConfigLoadStart || e instanceof RouteConfigLoadEnd) { + events.push(e); + } + }); - loader.stubbedModules = {expected: LoadedModule}; - const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + loader.stubbedModules = {expected: LoadedModule}; + const fixture = createRoot(router, RootCmp); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); - router.navigateByUrl('/lazy/loaded/child'); - advance(fixture); + router.navigateByUrl('/lazy/loaded/child'); + advance(fixture); - expect(events.length).toEqual(2); - expect(events[0].toString()).toEqual('RouteConfigLoadStart(path: lazy)'); - expect(events[1].toString()).toEqual('RouteConfigLoadEnd(path: lazy)'); - }))); + expect(events.length).toEqual(2); + expect(events[0].toString()).toEqual('RouteConfigLoadStart(path: lazy)'); + expect(events[1].toString()).toEqual('RouteConfigLoadEnd(path: lazy)'); + }))); - it('throws an error when forRoot() is used in a lazy context', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'should not show'}) - class LazyLoadedComponent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('throws an error when forRoot() is used in a lazy context', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({selector: 'lazy', template: 'should not show'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: [RouterModule.forRoot([{path: 'loaded', component: LazyLoadedComponent}])] - }) - class LoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: + [RouterModule.forRoot([{path: 'loaded', component: LazyLoadedComponent}])] + }) + class LoadedModule { + } - loader.stubbedModules = {expected: LoadedModule}; + loader.stubbedModules = {expected: LoadedModule}; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); - let recordedError: any = null; - router.navigateByUrl('/lazy/loaded') !.catch(err => recordedError = err); - advance(fixture); - expect(recordedError.message) - .toEqual( - `RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`); - }))); + let recordedError: any = null; + router.navigateByUrl('/lazy/loaded') !.catch(err => recordedError = err); + advance(fixture); + expect(recordedError.message) + .toEqual( + `RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`); + }))); - it('should combine routes from multiple modules into a single configuration', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'lazy-loaded-2'}) - class LazyComponent2 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should combine routes from multiple modules into a single configuration', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({selector: 'lazy', template: 'lazy-loaded-2'}) + class LazyComponent2 { + } - @NgModule({ - declarations: [LazyComponent2], - imports: [RouterModule.forChild([{path: 'loaded', component: LazyComponent2}])] - }) - class SiblingOfLoadedModule { - } + @NgModule({ + declarations: [LazyComponent2], + imports: [RouterModule.forChild([{path: 'loaded', component: LazyComponent2}])] + }) + class SiblingOfLoadedModule { + } - @Component({selector: 'lazy', template: 'lazy-loaded-1'}) - class LazyComponent1 { - } + @Component({selector: 'lazy', template: 'lazy-loaded-1'}) + class LazyComponent1 { + } - @NgModule({ - declarations: [LazyComponent1], - imports: [ - RouterModule.forChild([{path: 'loaded', component: LazyComponent1}]), - SiblingOfLoadedModule - ] - }) - class LoadedModule { - } + @NgModule({ + declarations: [LazyComponent1], + imports: [ + RouterModule.forChild([{path: 'loaded', component: LazyComponent1}]), + SiblingOfLoadedModule + ] + }) + class LoadedModule { + } - loader.stubbedModules = {expected1: LoadedModule, expected2: SiblingOfLoadedModule}; + loader.stubbedModules = { + expected1: LoadedModule, + expected2: SiblingOfLoadedModule + }; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - {path: 'lazy1', loadChildren: 'expected1'}, - {path: 'lazy2', loadChildren: 'expected2'} - ]); + router.resetConfig([ + {path: 'lazy1', loadChildren: 'expected1'}, + {path: 'lazy2', loadChildren: 'expected2'} + ]); - router.navigateByUrl('/lazy1/loaded'); - advance(fixture); - expect(location.path()).toEqual('/lazy1/loaded'); + router.navigateByUrl('/lazy1/loaded'); + advance(fixture); + expect(location.path()).toEqual('/lazy1/loaded'); - router.navigateByUrl('/lazy2/loaded'); - advance(fixture); - expect(location.path()).toEqual('/lazy2/loaded'); - }))); + router.navigateByUrl('/lazy2/loaded'); + advance(fixture); + expect(location.path()).toEqual('/lazy2/loaded'); + }))); - it('should allow lazy loaded module in named outlet', - fakeAsync(inject( - [Router, NgModuleFactoryLoader], (router: Router, loader: SpyNgModuleFactoryLoader) => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should allow lazy loaded module in named outlet', + fakeAsync(inject( + [Router, NgModuleFactoryLoader], + (router: Router, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyComponent { - } + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyComponent { + } - @NgModule({ - declarations: [LazyComponent], - imports: [RouterModule.forChild([{path: '', component: LazyComponent}])] - }) - class LazyLoadedModule { - } + @NgModule({ + declarations: [LazyComponent], + imports: [RouterModule.forChild([{path: '', component: LazyComponent}])] + }) + class LazyLoadedModule { + } - loader.stubbedModules = {lazyModule: LazyLoadedModule}; + loader.stubbedModules = {lazyModule: LazyLoadedModule}; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'team/:id', - component: TeamCmp, - children: [ - {path: 'user/:name', component: UserCmp}, - {path: 'lazy', loadChildren: 'lazyModule', outlet: 'right'}, - ] - }]); + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'user/:name', component: UserCmp}, + {path: 'lazy', loadChildren: 'lazyModule', outlet: 'right'}, + ] + }]); - router.navigateByUrl('/team/22/user/john'); - advance(fixture); + router.navigateByUrl('/team/22/user/john'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ user john, right: ]'); + expect(fixture.nativeElement).toHaveText('team 22 [ user john, right: ]'); - router.navigateByUrl('/team/22/(user/john//right:lazy)'); - advance(fixture); + router.navigateByUrl('/team/22/(user/john//right:lazy)'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('team 22 [ user john, right: lazy-loaded ]'); - }))); + expect(fixture.nativeElement) + .toHaveText('team 22 [ user john, right: lazy-loaded ]'); + }))); it('should allow componentless named outlet to render children', fakeAsync(inject( @@ -3793,52 +3888,55 @@ describe('Integration', () => { }); }); - it('should use the injector of the lazily-loaded configuration', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - loader.stubbedModules = {expected: LoadedModule}; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should use the injector of the lazily-loaded configuration', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + loader.stubbedModules = {expected: LoadedModule}; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'eager-parent', - component: EagerParentComponent, - children: [{path: 'lazy', loadChildren: 'expected'}] - }]); + router.resetConfig([{ + path: 'eager-parent', + component: EagerParentComponent, + children: [{path: 'lazy', loadChildren: 'expected'}] + }]); - router.navigateByUrl('/eager-parent/lazy/lazy-parent/lazy-child'); - advance(fixture); + router.navigateByUrl('/eager-parent/lazy/lazy-parent/lazy-child'); + advance(fixture); - expect(location.path()).toEqual('/eager-parent/lazy/lazy-parent/lazy-child'); - expect(fixture.nativeElement).toHaveText('eager-parent lazy-parent lazy-child'); - }))); + expect(location.path()).toEqual('/eager-parent/lazy/lazy-parent/lazy-child'); + expect(fixture.nativeElement).toHaveText('eager-parent lazy-parent lazy-child'); + }))); }); - it('works when given a callback', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], (router: Router, location: Location) => { - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyLoadedComponent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('works when given a callback', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], (router: Router, location: Location) => { + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])], - }) - class LoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: + [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])], + }) + class LoadedModule { + } - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: () => LoadedModule}]); + router.resetConfig([{path: 'lazy', loadChildren: () => LoadedModule}]); - router.navigateByUrl('/lazy/loaded'); - advance(fixture); + router.navigateByUrl('/lazy/loaded'); + advance(fixture); - expect(location.path()).toEqual('/lazy/loaded'); - expect(fixture.nativeElement).toHaveText('lazy-loaded'); - }))); + expect(location.path()).toEqual('/lazy/loaded'); + expect(fixture.nativeElement).toHaveText('lazy-loaded'); + }))); it('error emit an error when cannot load a config', fakeAsync(inject( @@ -3864,59 +3962,62 @@ describe('Integration', () => { ]); }))); - it('should work with complex redirect rules', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyLoadedComponent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should work with complex redirect rules', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])], - }) - class LoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: + [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])], + }) + class LoadedModule { + } - loader.stubbedModules = {lazy: LoadedModule}; - const fixture = createRoot(router, RootCmp); + loader.stubbedModules = {lazy: LoadedModule}; + const fixture = createRoot(router, RootCmp); - router.resetConfig( - [{path: 'lazy', loadChildren: 'lazy'}, {path: '**', redirectTo: 'lazy'}]); + router.resetConfig( + [{path: 'lazy', loadChildren: 'lazy'}, {path: '**', redirectTo: 'lazy'}]); - router.navigateByUrl('/lazy/loaded'); - advance(fixture); + router.navigateByUrl('/lazy/loaded'); + advance(fixture); - expect(location.path()).toEqual('/lazy/loaded'); - }))); + expect(location.path()).toEqual('/lazy/loaded'); + }))); - it('should work with wildcard route', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'lazy-loaded'}) - class LazyLoadedComponent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should work with wildcard route', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: [RouterModule.forChild([{path: '', component: LazyLoadedComponent}])], - }) - class LazyLoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: [RouterModule.forChild([{path: '', component: LazyLoadedComponent}])], + }) + class LazyLoadedModule { + } - loader.stubbedModules = {lazy: LazyLoadedModule}; - const fixture = createRoot(router, RootCmp); + loader.stubbedModules = {lazy: LazyLoadedModule}; + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: '**', loadChildren: 'lazy'}]); + router.resetConfig([{path: '**', loadChildren: 'lazy'}]); - router.navigateByUrl('/lazy'); - advance(fixture); + router.navigateByUrl('/lazy'); + advance(fixture); - expect(location.path()).toEqual('/lazy'); - expect(fixture.nativeElement).toHaveText('lazy-loaded'); - }))); + expect(location.path()).toEqual('/lazy'); + expect(fixture.nativeElement).toHaveText('lazy-loaded'); + }))); describe('preloading', () => { beforeEach(() => { @@ -3926,50 +4027,52 @@ describe('Integration', () => { preloader.setUpPreloading(); }); - it('should work', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({selector: 'lazy', template: 'should not show'}) - class LazyLoadedComponent { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should work', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({selector: 'lazy', template: 'should not show'}) + class LazyLoadedComponent { + } - @NgModule({ - declarations: [LazyLoadedComponent], - imports: [RouterModule.forChild( - [{path: 'LoadedModule2', component: LazyLoadedComponent}])] - }) - class LoadedModule2 { - } + @NgModule({ + declarations: [LazyLoadedComponent], + imports: [RouterModule.forChild( + [{path: 'LoadedModule2', component: LazyLoadedComponent}])] + }) + class LoadedModule2 { + } - @NgModule({ - imports: - [RouterModule.forChild([{path: 'LoadedModule1', loadChildren: 'expected2'}])] - }) - class LoadedModule1 { - } + @NgModule({ + imports: [RouterModule.forChild( + [{path: 'LoadedModule1', loadChildren: 'expected2'}])] + }) + class LoadedModule1 { + } - loader.stubbedModules = {expected: LoadedModule1, expected2: LoadedModule2}; + loader.stubbedModules = {expected: LoadedModule1, expected2: LoadedModule2}; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - {path: 'blank', component: BlankCmp}, {path: 'lazy', loadChildren: 'expected'} - ]); + router.resetConfig([ + {path: 'blank', component: BlankCmp}, + {path: 'lazy', loadChildren: 'expected'} + ]); - router.navigateByUrl('/blank'); - advance(fixture); + router.navigateByUrl('/blank'); + advance(fixture); - const config = router.config as any; - const firstConfig = config[1]._loadedConfig !; + const config = router.config as any; + const firstConfig = config[1]._loadedConfig !; - expect(firstConfig).toBeDefined(); - expect(firstConfig.routes[0].path).toEqual('LoadedModule1'); + expect(firstConfig).toBeDefined(); + expect(firstConfig.routes[0].path).toEqual('LoadedModule1'); - const secondConfig = firstConfig.routes[0]._loadedConfig !; - expect(secondConfig).toBeDefined(); - expect(secondConfig.routes[0].path).toEqual('LoadedModule2'); - }))); + const secondConfig = firstConfig.routes[0]._loadedConfig !; + expect(secondConfig).toBeDefined(); + expect(secondConfig.routes[0].path).toEqual('LoadedModule2'); + }))); }); @@ -4135,41 +4238,43 @@ describe('Integration', () => { class LazyLoadedModule { } - it('should not ignore empty path when in legacy mode', - fakeAsync(inject( - [Router, NgModuleFactoryLoader], - (router: Router, loader: SpyNgModuleFactoryLoader) => { - router.relativeLinkResolution = 'legacy'; - loader.stubbedModules = {expected: LazyLoadedModule}; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not ignore empty path when in legacy mode', + fakeAsync(inject( + [Router, NgModuleFactoryLoader], + (router: Router, loader: SpyNgModuleFactoryLoader) => { + router.relativeLinkResolution = 'legacy'; + loader.stubbedModules = {expected: LazyLoadedModule}; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); - router.navigateByUrl('/lazy/foo/bar'); - advance(fixture); + router.navigateByUrl('/lazy/foo/bar'); + advance(fixture); - const link = fixture.nativeElement.querySelector('a'); - expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple'); - }))); + const link = fixture.nativeElement.querySelector('a'); + expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple'); + }))); - it('should ignore empty path when in corrected mode', - fakeAsync(inject( - [Router, NgModuleFactoryLoader], - (router: Router, loader: SpyNgModuleFactoryLoader) => { - router.relativeLinkResolution = 'corrected'; - loader.stubbedModules = {expected: LazyLoadedModule}; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should ignore empty path when in corrected mode', + fakeAsync(inject( + [Router, NgModuleFactoryLoader], + (router: Router, loader: SpyNgModuleFactoryLoader) => { + router.relativeLinkResolution = 'corrected'; + loader.stubbedModules = {expected: LazyLoadedModule}; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); - router.navigateByUrl('/lazy/foo/bar'); - advance(fixture); + router.navigateByUrl('/lazy/foo/bar'); + advance(fixture); - const link = fixture.nativeElement.querySelector('a'); - expect(link.getAttribute('href')).toEqual('/lazy/foo/simple'); - }))); + const link = fixture.nativeElement.querySelector('a'); + expect(link.getAttribute('href')).toEqual('/lazy/foo/simple'); + }))); }); }); @@ -4216,142 +4321,145 @@ describe('Integration', () => { } } - it('should support attaching & detaching fragments', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-???: assertion failures') && + it('should support attaching & detaching fragments', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.routeReuseStrategy = new AttachDetachReuseStrategy(); + router.routeReuseStrategy = new AttachDetachReuseStrategy(); - router.resetConfig([ - { - path: 'a', - component: TeamCmp, - children: [{path: 'b', component: SimpleCmp}], - }, - {path: 'c', component: UserCmp}, - ]); + router.resetConfig([ + { + path: 'a', + component: TeamCmp, + children: [{path: 'b', component: SimpleCmp}], + }, + {path: 'c', component: UserCmp}, + ]); - router.navigateByUrl('/a/b'); - advance(fixture); - const teamCmp = fixture.debugElement.children[1].componentInstance; - const simpleCmp = fixture.debugElement.children[1].children[1].componentInstance; - expect(location.path()).toEqual('/a/b'); - expect(teamCmp).toBeDefined(); - expect(simpleCmp).toBeDefined(); + router.navigateByUrl('/a/b'); + advance(fixture); + const teamCmp = fixture.debugElement.children[1].componentInstance; + const simpleCmp = fixture.debugElement.children[1].children[1].componentInstance; + expect(location.path()).toEqual('/a/b'); + expect(teamCmp).toBeDefined(); + expect(simpleCmp).toBeDefined(); - router.navigateByUrl('/c'); - advance(fixture); - expect(location.path()).toEqual('/c'); - expect(fixture.debugElement.children[1].componentInstance).toBeAnInstanceOf(UserCmp); + router.navigateByUrl('/c'); + advance(fixture); + expect(location.path()).toEqual('/c'); + expect(fixture.debugElement.children[1].componentInstance).toBeAnInstanceOf(UserCmp); - router.navigateByUrl('/a;p=1/b;p=2'); - advance(fixture); - const teamCmp2 = fixture.debugElement.children[1].componentInstance; - const simpleCmp2 = fixture.debugElement.children[1].children[1].componentInstance; - expect(location.path()).toEqual('/a;p=1/b;p=2'); - expect(teamCmp2).toBe(teamCmp); - expect(simpleCmp2).toBe(simpleCmp); + router.navigateByUrl('/a;p=1/b;p=2'); + advance(fixture); + const teamCmp2 = fixture.debugElement.children[1].componentInstance; + const simpleCmp2 = fixture.debugElement.children[1].children[1].componentInstance; + expect(location.path()).toEqual('/a;p=1/b;p=2'); + expect(teamCmp2).toBe(teamCmp); + expect(simpleCmp2).toBe(simpleCmp); - expect(teamCmp.route).toBe(router.routerState.root.firstChild); - expect(teamCmp.route.snapshot).toBe(router.routerState.snapshot.root.firstChild); - expect(teamCmp.route.snapshot.params).toEqual({p: '1'}); - expect(teamCmp.route.firstChild.snapshot.params).toEqual({p: '2'}); - }))); + expect(teamCmp.route).toBe(router.routerState.root.firstChild); + expect(teamCmp.route.snapshot).toBe(router.routerState.snapshot.root.firstChild); + expect(teamCmp.route.snapshot.params).toEqual({p: '1'}); + expect(teamCmp.route.firstChild.snapshot.params).toEqual({p: '2'}); + }))); - it('should support shorter lifecycles', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); - router.routeReuseStrategy = new ShortLifecycle(); + fixmeIvy('FW-???: assertion failures') && + it('should support shorter lifecycles', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); + router.routeReuseStrategy = new ShortLifecycle(); - router.resetConfig([{path: 'a', component: SimpleCmp}]); + router.resetConfig([{path: 'a', component: SimpleCmp}]); - router.navigateByUrl('/a'); - advance(fixture); - const simpleCmp1 = fixture.debugElement.children[1].componentInstance; - expect(location.path()).toEqual('/a'); + router.navigateByUrl('/a'); + advance(fixture); + const simpleCmp1 = fixture.debugElement.children[1].componentInstance; + expect(location.path()).toEqual('/a'); - router.navigateByUrl('/a;p=1'); - advance(fixture); - expect(location.path()).toEqual('/a;p=1'); - const simpleCmp2 = fixture.debugElement.children[1].componentInstance; - expect(simpleCmp1).not.toBe(simpleCmp2); - }))); + router.navigateByUrl('/a;p=1'); + advance(fixture); + expect(location.path()).toEqual('/a;p=1'); + const simpleCmp2 = fixture.debugElement.children[1].componentInstance; + expect(simpleCmp1).not.toBe(simpleCmp2); + }))); - it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation', - fakeAsync(() => { - @Component({ - selector: 'root-cmp', - template: - '
' - }) - class RootCmpWithCondOutlet implements OnDestroy { - private subscription: Subscription; - public isToolpanelShowing: boolean = false; + fixmeIvy('FW-???: Error: Cannot match any routes. URL Segment: \'a\'') && + it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation', + fakeAsync(() => { + @Component({ + selector: 'root-cmp', + template: + '
' + }) + class RootCmpWithCondOutlet implements OnDestroy { + private subscription: Subscription; + public isToolpanelShowing: boolean = false; - constructor(router: Router) { - this.subscription = - router.events.pipe(filter(event => event instanceof NavigationEnd)) - .subscribe( - () => this.isToolpanelShowing = - !!router.parseUrl(router.url).root.children['toolpanel']); - } + constructor(router: Router) { + this.subscription = + router.events.pipe(filter(event => event instanceof NavigationEnd)) + .subscribe( + () => this.isToolpanelShowing = + !!router.parseUrl(router.url).root.children['toolpanel']); + } - public ngOnDestroy(): void { this.subscription.unsubscribe(); } - } + public ngOnDestroy(): void { this.subscription.unsubscribe(); } + } - @Component({selector: 'tool-1-cmp', template: 'Tool 1 showing'}) - class Tool1Component { - } + @Component({selector: 'tool-1-cmp', template: 'Tool 1 showing'}) + class Tool1Component { + } - @Component({selector: 'tool-2-cmp', template: 'Tool 2 showing'}) - class Tool2Component { - } + @Component({selector: 'tool-2-cmp', template: 'Tool 2 showing'}) + class Tool2Component { + } - @NgModule({ - declarations: [RootCmpWithCondOutlet, Tool1Component, Tool2Component], - imports: [ - CommonModule, - RouterTestingModule.withRoutes([ - {path: 'a', outlet: 'toolpanel', component: Tool1Component}, - {path: 'b', outlet: 'toolpanel', component: Tool2Component}, - ]), - ], - }) - class TestModule { - } + @NgModule({ + declarations: [RootCmpWithCondOutlet, Tool1Component, Tool2Component], + imports: [ + CommonModule, + RouterTestingModule.withRoutes([ + {path: 'a', outlet: 'toolpanel', component: Tool1Component}, + {path: 'b', outlet: 'toolpanel', component: Tool2Component}, + ]), + ], + }) + class TestModule { + } - TestBed.configureTestingModule({imports: [TestModule]}); + TestBed.configureTestingModule({imports: [TestModule]}); - const router: Router = TestBed.get(Router); - router.routeReuseStrategy = new AttachDetachReuseStrategy(); + const router: Router = TestBed.get(Router); + router.routeReuseStrategy = new AttachDetachReuseStrategy(); - const fixture = createRoot(router, RootCmpWithCondOutlet); + const fixture = createRoot(router, RootCmpWithCondOutlet); - // Activate 'tool-1' - router.navigate([{outlets: {toolpanel: 'a'}}]); - advance(fixture); - expect(fixture).toContainComponent(Tool1Component, '(a)'); + // Activate 'tool-1' + router.navigate([{outlets: {toolpanel: 'a'}}]); + advance(fixture); + expect(fixture).toContainComponent(Tool1Component, '(a)'); - // Deactivate 'tool-1' - router.navigate([{outlets: {toolpanel: null}}]); - advance(fixture); - expect(fixture).not.toContainComponent(Tool1Component, '(b)'); + // Deactivate 'tool-1' + router.navigate([{outlets: {toolpanel: null}}]); + advance(fixture); + expect(fixture).not.toContainComponent(Tool1Component, '(b)'); - // Activate 'tool-1' - router.navigate([{outlets: {toolpanel: 'a'}}]); - advance(fixture); - expect(fixture).toContainComponent(Tool1Component, '(c)'); + // Activate 'tool-1' + router.navigate([{outlets: {toolpanel: 'a'}}]); + advance(fixture); + expect(fixture).toContainComponent(Tool1Component, '(c)'); - // Deactivate 'tool-1' - router.navigate([{outlets: {toolpanel: null}}]); - advance(fixture); - expect(fixture).not.toContainComponent(Tool1Component, '(d)'); + // Deactivate 'tool-1' + router.navigate([{outlets: {toolpanel: null}}]); + advance(fixture); + expect(fixture).not.toContainComponent(Tool1Component, '(d)'); - // Activate 'tool-2' - router.navigate([{outlets: {toolpanel: 'b'}}]); - advance(fixture); - expect(fixture).toContainComponent(Tool2Component, '(e)'); - })); + // Activate 'tool-2' + router.navigate([{outlets: {toolpanel: 'b'}}]); + advance(fixture); + expect(fixture).toContainComponent(Tool2Component, '(e)'); + })); }); }); diff --git a/packages/router/test/operators/prioritized_guard_value.spec.ts b/packages/router/test/operators/prioritized_guard_value.spec.ts index 54de147987..8ee10e699e 100644 --- a/packages/router/test/operators/prioritized_guard_value.spec.ts +++ b/packages/router/test/operators/prioritized_guard_value.spec.ts @@ -8,6 +8,7 @@ import {TestBed} from '@angular/core/testing'; +import {RouterTestingModule} from '@angular/router/testing'; import {Observable, Observer, of } from 'rxjs'; import {every, mergeMap} from 'rxjs/operators'; import {TestScheduler} from 'rxjs/testing'; @@ -15,7 +16,6 @@ import {TestScheduler} from 'rxjs/testing'; import {prioritizedGuardValue} from '../../src/operators/prioritized_guard_value'; import {Router} from '../../src/router'; import {UrlTree} from '../../src/url_tree'; -import {RouterTestingModule} from '../../testing/src/router_testing_module'; describe('prioritizedGuardValue operator', () => { diff --git a/packages/router/test/regression_integration.spec.ts b/packages/router/test/regression_integration.spec.ts index ab1d0681be..9aab369a86 100644 --- a/packages/router/test/regression_integration.spec.ts +++ b/packages/router/test/regression_integration.spec.ts @@ -9,21 +9,22 @@ import {CommonModule} from '@angular/common'; import {Component, ContentChild, NgModule, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing'; -import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; +import {fixmeIvy} from '@angular/private/testing'; import {Router} from '@angular/router'; import {RouterTestingModule} from '@angular/router/testing'; describe('Integration', () => { describe('routerLinkActive', () => { - it('should not cause infinite loops in the change detection - #15825', fakeAsync(() => { - @Component({selector: 'simple', template: 'simple'}) - class SimpleCmp { - } + fixmeIvy('FW-662: Components without selector are not supported') && + it('should not cause infinite loops in the change detection - #15825', fakeAsync(() => { + @Component({selector: 'simple', template: 'simple'}) + class SimpleCmp { + } - @Component({ - selector: 'some-root', - template: ` + @Component({ + selector: 'some-root', + template: `
@@ -31,36 +32,37 @@ describe('Integration', () => { ` - }) - class MyCmp { - show: boolean = false; - } + }) + class MyCmp { + show: boolean = false; + } - @NgModule({ - imports: [CommonModule, RouterTestingModule], - declarations: [MyCmp, SimpleCmp], - entryComponents: [SimpleCmp], - }) - class MyModule { - } + @NgModule({ + imports: [CommonModule, RouterTestingModule], + declarations: [MyCmp, SimpleCmp], + entryComponents: [SimpleCmp], + }) + class MyModule { + } - TestBed.configureTestingModule({imports: [MyModule]}); + TestBed.configureTestingModule({imports: [MyModule]}); - const router: Router = TestBed.get(Router); - const fixture = createRoot(router, MyCmp); - router.resetConfig([{path: 'simple', component: SimpleCmp}]); + const router: Router = TestBed.get(Router); + const fixture = createRoot(router, MyCmp); + router.resetConfig([{path: 'simple', component: SimpleCmp}]); - router.navigateByUrl('/simple'); - advance(fixture); + router.navigateByUrl('/simple'); + advance(fixture); - const instance = fixture.componentInstance; - instance.show = true; - expect(() => advance(fixture)).not.toThrow(); - })); + const instance = fixture.componentInstance; + instance.show = true; + expect(() => advance(fixture)).not.toThrow(); + })); - it('should set isActive right after looking at its children -- #18983', fakeAsync(() => { - @Component({ - template: ` + fixmeIvy('FW-662: Components without selector are not supported') && + it('should set isActive right after looking at its children -- #18983', fakeAsync(() => { + @Component({ + template: `
isActive: {{rla.isActive}} @@ -71,43 +73,43 @@ describe('Integration', () => {
` - }) - class ComponentWithRouterLink { - // TODO(issue/24571): remove '!'. - @ViewChild(TemplateRef) templateRef !: TemplateRef; - // TODO(issue/24571): remove '!'. - @ViewChild('container', {read: ViewContainerRef}) container !: ViewContainerRef; + }) + class ComponentWithRouterLink { + // TODO(issue/24571): remove '!'. + @ViewChild(TemplateRef) templateRef !: TemplateRef; + // TODO(issue/24571): remove '!'. + @ViewChild('container', {read: ViewContainerRef}) container !: ViewContainerRef; - addLink() { - this.container.createEmbeddedView(this.templateRef, {$implicit: '/simple'}); - } + addLink() { + this.container.createEmbeddedView(this.templateRef, {$implicit: '/simple'}); + } - removeLink() { this.container.clear(); } - } + removeLink() { this.container.clear(); } + } - @Component({template: 'simple'}) - class SimpleCmp { - } + @Component({template: 'simple'}) + class SimpleCmp { + } - TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([{path: 'simple', component: SimpleCmp}])], - declarations: [ComponentWithRouterLink, SimpleCmp] - }); + TestBed.configureTestingModule({ + imports: [RouterTestingModule.withRoutes([{path: 'simple', component: SimpleCmp}])], + declarations: [ComponentWithRouterLink, SimpleCmp] + }); - const router: Router = TestBed.get(Router); - const fixture = createRoot(router, ComponentWithRouterLink); - router.navigateByUrl('/simple'); - advance(fixture); + const router: Router = TestBed.get(Router); + const fixture = createRoot(router, ComponentWithRouterLink); + router.navigateByUrl('/simple'); + advance(fixture); - fixture.componentInstance.addLink(); - fixture.detectChanges(); + fixture.componentInstance.addLink(); + fixture.detectChanges(); - fixture.componentInstance.removeLink(); - advance(fixture); - advance(fixture); + fixture.componentInstance.removeLink(); + advance(fixture); + advance(fixture); - expect(fixture.nativeElement.innerHTML).toContain('isActive: false'); - })); + expect(fixture.nativeElement.innerHTML).toContain('isActive: false'); + })); }); diff --git a/packages/router/test/router.spec.ts b/packages/router/test/router.spec.ts index 81da038b92..56c13a4a28 100644 --- a/packages/router/test/router.spec.ts +++ b/packages/router/test/router.spec.ts @@ -8,6 +8,7 @@ import {Location} from '@angular/common'; import {TestBed, inject} from '@angular/core/testing'; +import {RouterTestingModule} from '@angular/router/testing'; import {of } from 'rxjs'; import {Routes} from '../src/config'; @@ -20,7 +21,6 @@ import {RouterStateSnapshot, createEmptyStateSnapshot} from '../src/router_state import {DefaultUrlSerializer, UrlTree} from '../src/url_tree'; import {getAllRouteGuards} from '../src/utils/preactivation'; import {TreeNode} from '../src/utils/tree'; -import {RouterTestingModule} from '../testing/src/router_testing_module'; import {Logger, createActivatedRouteSnapshot, provideTokenLogger} from './helpers'; diff --git a/packages/router/test/router_preloader.spec.ts b/packages/router/test/router_preloader.spec.ts index 8df0e8bc46..5b65c9eaca 100644 --- a/packages/router/test/router_preloader.spec.ts +++ b/packages/router/test/router_preloader.spec.ts @@ -8,10 +8,11 @@ import {Compiler, Component, NgModule, NgModuleFactoryLoader, NgModuleRef} from '@angular/core'; import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing'; +import {fixmeIvy} from '@angular/private/testing'; +import {PreloadAllModules, PreloadingStrategy, RouterPreloader} from '@angular/router'; import {Route, RouteConfigLoadEnd, RouteConfigLoadStart, Router, RouterModule} from '../index'; import {LoadedRouterConfig} from '../src/config'; -import {PreloadAllModules, PreloadingStrategy, RouterPreloader} from '../src/router_preloader'; import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing'; describe('RouterPreloader', () => { @@ -35,19 +36,20 @@ describe('RouterPreloader', () => { }); }); - it('should work', - fakeAsync(inject( - [NgModuleFactoryLoader, RouterPreloader, Router], - (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { - loader.stubbedModules = {expected: LoadedModule}; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should work', + fakeAsync(inject( + [NgModuleFactoryLoader, RouterPreloader, Router], + (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { + loader.stubbedModules = {expected: LoadedModule}; - preloader.preload().subscribe(() => {}); + preloader.preload().subscribe(() => {}); - tick(); + tick(); - const c = router.config; - expect((c[0] as any)._loadedConfig).not.toBeDefined(); - }))); + const c = router.config; + expect((c[0] as any)._loadedConfig).not.toBeDefined(); + }))); }); describe('should preload configurations', () => { @@ -58,63 +60,64 @@ describe('RouterPreloader', () => { }); }); - it('should work', - fakeAsync(inject( - [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], - (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, - testModule: NgModuleRef) => { - const events: Array = []; - @NgModule({ - declarations: [LazyLoadedCmp], - imports: - [RouterModule.forChild([{path: 'LoadedModule2', component: LazyLoadedCmp}])] - }) - class LoadedModule2 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should work', + fakeAsync(inject( + [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], + (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, + testModule: NgModuleRef) => { + const events: Array = []; + @NgModule({ + declarations: [LazyLoadedCmp], + imports: [RouterModule.forChild( + [{path: 'LoadedModule2', component: LazyLoadedCmp}])] + }) + class LoadedModule2 { + } - @NgModule({ - imports: - [RouterModule.forChild([{path: 'LoadedModule1', loadChildren: 'expected2'}])] - }) - class LoadedModule1 { - } + @NgModule({ + imports: [RouterModule.forChild( + [{path: 'LoadedModule1', loadChildren: 'expected2'}])] + }) + class LoadedModule1 { + } - router.events.subscribe(e => { - if (e instanceof RouteConfigLoadEnd || e instanceof RouteConfigLoadStart) { - events.push(e); - } - }); + router.events.subscribe(e => { + if (e instanceof RouteConfigLoadEnd || e instanceof RouteConfigLoadStart) { + events.push(e); + } + }); - loader.stubbedModules = { - expected: LoadedModule1, - expected2: LoadedModule2, - }; + loader.stubbedModules = { + expected: LoadedModule1, + expected2: LoadedModule2, + }; - preloader.preload().subscribe(() => {}); + preloader.preload().subscribe(() => {}); - tick(); + tick(); - const c = router.config; - expect(c[0].loadChildren).toEqual('expected'); + const c = router.config; + expect(c[0].loadChildren).toEqual('expected'); - const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; - const module: any = loadedConfig.module; - expect(loadedConfig.routes[0].path).toEqual('LoadedModule1'); - expect(module._parent).toBe(testModule); + const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; + const module: any = loadedConfig.module; + expect(loadedConfig.routes[0].path).toEqual('LoadedModule1'); + expect(module._parent).toBe(testModule); - const loadedConfig2: LoadedRouterConfig = - (loadedConfig.routes[0] as any)._loadedConfig !; - const module2: any = loadedConfig2.module; - expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2'); - expect(module2._parent).toBe(module); + const loadedConfig2: LoadedRouterConfig = + (loadedConfig.routes[0] as any)._loadedConfig !; + const module2: any = loadedConfig2.module; + expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2'); + expect(module2._parent).toBe(module); - expect(events.map(e => e.toString())).toEqual([ - 'RouteConfigLoadStart(path: lazy)', - 'RouteConfigLoadEnd(path: lazy)', - 'RouteConfigLoadStart(path: LoadedModule1)', - 'RouteConfigLoadEnd(path: LoadedModule1)', - ]); - }))); + expect(events.map(e => e.toString())).toEqual([ + 'RouteConfigLoadStart(path: lazy)', + 'RouteConfigLoadEnd(path: lazy)', + 'RouteConfigLoadStart(path: LoadedModule1)', + 'RouteConfigLoadEnd(path: LoadedModule1)', + ]); + }))); }); describe('should support modules that have already been loaded', () => { @@ -125,57 +128,59 @@ describe('RouterPreloader', () => { }); }); - it('should work', fakeAsync(inject( - [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler], - (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, - router: Router, testModule: NgModuleRef, compiler: Compiler) => { - @NgModule() - class LoadedModule2 { - } + fixmeIvy('FW-???: Cannot read property \'declarations\' of undefined') && + it('should work', + fakeAsync(inject( + [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler], + (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, + testModule: NgModuleRef, compiler: Compiler) => { + @NgModule() + class LoadedModule2 { + } - const module2 = compiler.compileModuleSync(LoadedModule2).create(null); + const module2 = compiler.compileModuleSync(LoadedModule2).create(null); - @NgModule({ - imports: [RouterModule.forChild([ - { - path: 'LoadedModule2', - loadChildren: 'no', - _loadedConfig: { - routes: [{path: 'LoadedModule3', loadChildren: 'expected3'}], - module: module2, - } - }, - ])] - }) - class LoadedModule1 { - } + @NgModule({ + imports: [RouterModule.forChild([ + { + path: 'LoadedModule2', + loadChildren: 'no', + _loadedConfig: { + routes: [{path: 'LoadedModule3', loadChildren: 'expected3'}], + module: module2, + } + }, + ])] + }) + class LoadedModule1 { + } - @NgModule({imports: [RouterModule.forChild([])]}) - class LoadedModule3 { - } + @NgModule({imports: [RouterModule.forChild([])]}) + class LoadedModule3 { + } - loader.stubbedModules = { - expected: LoadedModule1, - expected3: LoadedModule3, - }; + loader.stubbedModules = { + expected: LoadedModule1, + expected3: LoadedModule3, + }; - preloader.preload().subscribe(() => {}); + preloader.preload().subscribe(() => {}); - tick(); + tick(); - const c = router.config; + const c = router.config; - const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; - const module: any = loadedConfig.module; - expect(module._parent).toBe(testModule); + const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; + const module: any = loadedConfig.module; + expect(module._parent).toBe(testModule); - const loadedConfig2: LoadedRouterConfig = - (loadedConfig.routes[0] as any)._loadedConfig !; - const loadedConfig3: LoadedRouterConfig = - (loadedConfig2.routes[0] as any)._loadedConfig !; - const module3: any = loadedConfig3.module; - expect(module3._parent).toBe(module2); - }))); + const loadedConfig2: LoadedRouterConfig = + (loadedConfig.routes[0] as any)._loadedConfig !; + const loadedConfig3: LoadedRouterConfig = + (loadedConfig2.routes[0] as any)._loadedConfig !; + const module3: any = loadedConfig3.module; + expect(module3._parent).toBe(module2); + }))); }); describe('should ignore errors', () => { @@ -195,20 +200,21 @@ describe('RouterPreloader', () => { }); }); - it('should work', - fakeAsync(inject( - [NgModuleFactoryLoader, RouterPreloader, Router], - (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { - loader.stubbedModules = {expected2: LoadedModule}; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should work', + fakeAsync(inject( + [NgModuleFactoryLoader, RouterPreloader, Router], + (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { + loader.stubbedModules = {expected2: LoadedModule}; - preloader.preload().subscribe(() => {}); + preloader.preload().subscribe(() => {}); - tick(); + tick(); - const c = router.config; - expect((c[0] as any)._loadedConfig).not.toBeDefined(); - expect((c[1] as any)._loadedConfig).toBeDefined(); - }))); + const c = router.config; + expect((c[0] as any)._loadedConfig).not.toBeDefined(); + expect((c[1] as any)._loadedConfig).toBeDefined(); + }))); }); describe('should copy loaded configs', () => { @@ -224,21 +230,22 @@ describe('RouterPreloader', () => { }); }); - it('should work', - fakeAsync(inject( - [NgModuleFactoryLoader, RouterPreloader, Router], - (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { - loader.stubbedModules = {expected: LoadedModule}; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should work', + fakeAsync(inject( + [NgModuleFactoryLoader, RouterPreloader, Router], + (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { + loader.stubbedModules = {expected: LoadedModule}; - preloader.preload().subscribe(() => {}); + preloader.preload().subscribe(() => {}); - tick(); + tick(); - const c = router.config as{_loadedConfig: LoadedRouterConfig}[]; - expect(c[0]._loadedConfig).toBeDefined(); - expect(c[0]._loadedConfig !.routes).not.toBe(configs); - expect(c[0]._loadedConfig !.routes[0]).not.toBe(configs[0]); - expect(c[0]._loadedConfig !.routes[0].component).toBe(configs[0].component); - }))); + const c = router.config as{_loadedConfig: LoadedRouterConfig}[]; + expect(c[0]._loadedConfig).toBeDefined(); + expect(c[0]._loadedConfig !.routes).not.toBe(configs); + expect(c[0]._loadedConfig !.routes[0]).not.toBe(configs[0]); + expect(c[0]._loadedConfig !.routes[0].component).toBe(configs[0].component); + }))); }); }); diff --git a/packages/router/test/spy_ng_module_factory_loader.spec.ts b/packages/router/test/spy_ng_module_factory_loader.spec.ts index 076f5c2a9f..6ddb2d7503 100644 --- a/packages/router/test/spy_ng_module_factory_loader.spec.ts +++ b/packages/router/test/spy_ng_module_factory_loader.spec.ts @@ -7,7 +7,7 @@ */ import {fakeAsync, tick} from '@angular/core/testing'; -import {SpyNgModuleFactoryLoader} from '../testing/src/router_testing_module'; +import {SpyNgModuleFactoryLoader} from '@angular/router/testing'; describe('SpyNgModuleFactoryLoader', () => { it('should invoke the compiler when the setter is called', () => {