test(ivy): run router tests with ivy on CI (#27195)

PR Close #27195
This commit is contained in:
Marc Laval 2018-11-20 17:02:35 +01:00 committed by Miško Hevery
parent 573fb783e1
commit 8ce59a583b
9 changed files with 2108 additions and 1993 deletions

View File

@ -51,6 +51,7 @@ System.config({
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'}, '@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser-dynamic/testing': {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/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/upgrade/static': {main: 'index.js', defaultExtension: 'js'},
'@angular/router/upgrade': {main: 'index.js', defaultExtension: 'js'}, '@angular/router/upgrade': {main: 'index.js', defaultExtension: 'js'},
'@angular/router/testing': {main: 'index.js', defaultExtension: 'js'}, '@angular/router/testing': {main: 'index.js', defaultExtension: 'js'},

View File

@ -76,6 +76,8 @@ module.exports = function(config) {
watched: false 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/*.js', included: false, watched: false},
{pattern: 'dist/all/@angular/upgrade/static/src/**/*.js', included: false, watched: false}, {pattern: 'dist/all/@angular/upgrade/static/src/**/*.js', included: false, watched: false},

View File

@ -12,6 +12,7 @@ ts_library(
"//packages/platform-browser", "//packages/platform-browser",
"//packages/platform-browser-dynamic", "//packages/platform-browser-dynamic",
"//packages/platform-browser/testing", "//packages/platform-browser/testing",
"//packages/private/testing",
"//packages/router", "//packages/router",
"//packages/router/testing", "//packages/router/testing",
"@rxjs", "@rxjs",
@ -23,9 +24,6 @@ ts_library(
jasmine_node_test( jasmine_node_test(
name = "test", name = "test",
bootstrap = ["angular/tools/testing/init_node_spec.js"], bootstrap = ["angular/tools/testing/init_node_spec.js"],
tags = [
"fixme-ivy-aot",
],
deps = [ deps = [
":test_lib", ":test_lib",
"//tools/testing:node", "//tools/testing:node",
@ -34,9 +32,6 @@ jasmine_node_test(
ts_web_test_suite( ts_web_test_suite(
name = "test_web", name = "test_web",
tags = [
"fixme-ivy-aot",
],
deps = [ deps = [
":test_lib", ":test_lib",
], ],

View File

@ -12,6 +12,7 @@ import {ChangeDetectionStrategy, Component, Injectable, NgModule, NgModuleFactor
import {ComponentFixture, TestBed, fakeAsync, flush, inject, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, fakeAsync, flush, inject, tick} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {expect} from '@angular/platform-browser/testing/src/matchers'; 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 {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 {Observable, Observer, Subscription, of } from 'rxjs';
import {filter, first, map, tap} from 'rxjs/operators'; import {filter, first, map, tap} from 'rxjs/operators';
@ -296,6 +297,7 @@ describe('Integration', () => {
beforeEach(() => TestBed.configureTestingModule({imports: [TestModule]})); beforeEach(() => TestBed.configureTestingModule({imports: [TestModule]}));
fixmeIvy('FW-???: assertion failures') &&
it('should work', it('should work',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -401,6 +403,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('it works!'); expect(fixture.nativeElement).toHaveText('it works!');
})); }));
fixmeIvy('FW-???: assertion failures') &&
it('should not error when no url left and no children are matching', it('should not error when no url left and no children are matching',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -424,6 +427,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
}))); })));
fixmeIvy('FW-???: Error: Timeout') &&
it('should work when an outlet is in an ngIf', it('should work when an outlet is in an ngIf',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -440,6 +444,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/child/simple'); expect(location.path()).toEqual('/child/simple');
}))); })));
fixmeIvy('FW-???: Error: 1 timer(s) still in the queue.') &&
it('should work when an outlet is added/removed', fakeAsync(() => { it('should work when an outlet is added/removed', fakeAsync(() => {
@Component({ @Component({
selector: 'someRoot', selector: 'someRoot',
@ -472,6 +477,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('[simple]'); expect(fixture.nativeElement).toHaveText('[simple]');
})); }));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should update location when navigating', fakeAsync(() => { it('should update location when navigating', fakeAsync(() => {
@Component({template: `record`}) @Component({template: `record`})
class RecordLocationCmp { class RecordLocationCmp {
@ -503,6 +509,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/record/33'); expect(location.path()).toEqual('/record/33');
})); }));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should skip location update when using NavigationExtras.skipLocationChange with navigateByUrl', it('should skip location update when using NavigationExtras.skipLocationChange with navigateByUrl',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp); const fixture = TestBed.createComponent(RootCmp);
@ -524,6 +531,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should skip location update when using NavigationExtras.skipLocationChange with navigate', it('should skip location update when using NavigationExtras.skipLocationChange with navigate',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp); const fixture = TestBed.createComponent(RootCmp);
@ -545,6 +553,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should eagerly update the URL with urlUpdateStrategy="eagar"', it('should eagerly update the URL with urlUpdateStrategy="eagar"',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp); const fixture = TestBed.createComponent(RootCmp);
@ -570,6 +579,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should navigate back and forward', it('should navigate back and forward',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -577,8 +587,9 @@ describe('Integration', () => {
router.resetConfig([{ router.resetConfig([{
path: 'team/:id', path: 'team/:id',
component: TeamCmp, component: TeamCmp,
children: children: [
[{path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp}] {path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp}
]
}]); }]);
let event: NavigationStart; let event: NavigationStart;
@ -611,6 +622,7 @@ describe('Integration', () => {
expect(event !.restoredState !.navigationId).toEqual(userVictorNavStart.id); expect(event !.restoredState !.navigationId).toEqual(userVictorNavStart.id);
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should navigate to the same url when config changes', it('should navigate to the same url when config changes',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -630,6 +642,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('route'); expect(fixture.nativeElement).toHaveText('route');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should navigate when locations changes', it('should navigate when locations changes',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -660,6 +673,7 @@ describe('Integration', () => {
]); ]);
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should update the location when the matched route does not change', it('should update the location when the matched route does not change',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -718,6 +732,7 @@ describe('Integration', () => {
}))); })));
}); });
fixmeIvy('FW-???: assertion failures') &&
it('should support secondary routes', fakeAsync(inject([Router], (router: Router) => { it('should support secondary routes', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -736,6 +751,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should support secondary routes in separate commands', it('should support secondary routes in separate commands',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -757,6 +773,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should deactivate outlets', fakeAsync(inject([Router], (router: Router) => { it('should deactivate outlets', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -778,6 +795,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: ]'); expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: ]');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should deactivate nested outlets', fakeAsync(inject([Router], (router: Router) => { it('should deactivate nested outlets', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -802,6 +820,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText(''); expect(fixture.nativeElement).toHaveText('');
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should set query params and fragment', fakeAsync(inject([Router], (router: Router) => { it('should set query params and fragment', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -816,6 +835,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('query: 2 fragment: fragment2'); expect(fixture.nativeElement).toHaveText('query: 2 fragment: fragment2');
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should ignore null and undefined query params', it('should ignore null and undefined query params',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -839,7 +859,9 @@ describe('Integration', () => {
])).toThrowError(`The requested path contains undefined segment at index 0`); ])).toThrowError(`The requested path contains undefined segment at index 0`);
}))); })));
it('should push params only when they change', fakeAsync(inject([Router], (router: Router) => { 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); const fixture = createRoot(router, RootCmp);
router.resetConfig([{ router.resetConfig([{
@ -867,6 +889,7 @@ describe('Integration', () => {
expect(user.snapshotParams).toEqual([{name: 'victor'}, {name: 'fedor'}]); expect(user.snapshotParams).toEqual([{name: 'victor'}, {name: 'fedor'}]);
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should work when navigating to /', fakeAsync(inject([Router], (router: Router) => { it('should work when navigating to /', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -886,6 +909,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('simple'); expect(fixture.nativeElement).toHaveText('simple');
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should cancel in-flight navigations', fakeAsync(inject([Router], (router: Router) => { it('should cancel in-flight navigations', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -1149,6 +1173,7 @@ describe('Integration', () => {
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should replace state when path is equal to current path', it('should replace state when path is equal to current path',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -1156,8 +1181,9 @@ describe('Integration', () => {
router.resetConfig([{ router.resetConfig([{
path: 'team/:id', path: 'team/:id',
component: TeamCmp, component: TeamCmp,
children: children: [
[{path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp}] {path: 'simple', component: SimpleCmp}, {path: 'user/:name', component: UserCmp}
]
}]); }]);
router.navigateByUrl('/team/33/simple'); router.navigateByUrl('/team/33/simple');
@ -1174,6 +1200,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/team/33/simple'); expect(location.path()).toEqual('/team/33/simple');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should handle componentless paths', it('should handle componentless paths',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmpWithTwoOutlets); const fixture = createRoot(router, RootCmpWithTwoOutlets);
@ -1215,6 +1242,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('primary [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', it('should not deactivate aux routes when navigating from a componentless routes',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, TwoOutletsCmp); const fixture = createRoot(router, TwoOutletsCmp);
@ -1236,6 +1264,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('[ simple, aux: user victor ]'); expect(fixture.nativeElement).toHaveText('[ simple, aux: user victor ]');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should emit an event when an outlet gets activated', fakeAsync(() => { it('should emit an event when an outlet gets activated', fakeAsync(() => {
@Component({ @Component({
selector: 'container', selector: 'container',
@ -1279,6 +1308,7 @@ describe('Integration', () => {
expect(cmp.deactivations[0] instanceof BlankCmp).toBe(true); expect(cmp.deactivations[0] instanceof BlankCmp).toBe(true);
})); }));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should update url and router state before activating components', it('should update url and router state before activating components',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
@ -1315,6 +1345,7 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should provide resolved data', fakeAsync(inject([Router], (router: Router) => { it('should provide resolved data', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmpWithTwoOutlets); const fixture = createRoot(router, RootCmpWithTwoOutlets);
@ -1323,7 +1354,8 @@ describe('Integration', () => {
data: {one: 1}, data: {one: 1},
resolve: {two: 'resolveTwo'}, resolve: {two: 'resolveTwo'},
children: [ children: [
{path: '', data: {three: 3}, resolve: {four: 'resolveFour'}, component: RouteCmp}, { {path: '', data: {three: 3}, resolve: {four: 'resolveFour'}, component: RouteCmp},
{
path: '', path: '',
data: {five: 5}, data: {five: 5},
resolve: {six: 'resolveSix'}, resolve: {six: 'resolveSix'},
@ -1393,6 +1425,7 @@ describe('Integration', () => {
expect(e).toEqual(null); expect(e).toEqual(null);
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should preserve resolved data', fakeAsync(inject([Router], (router: Router) => { it('should preserve resolved data', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -1416,6 +1449,7 @@ describe('Integration', () => {
expect(cmp.route.snapshot.data).toEqual({two: 2}); expect(cmp.route.snapshot.data).toEqual({two: 2});
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should rerun resolvers when the urls segments of a wildcard route change', it('should rerun resolvers when the urls segments of a wildcard route change',
fakeAsync(inject([Router, Location], (router: Router) => { fakeAsync(inject([Router, Location], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -1491,6 +1525,7 @@ describe('Integration', () => {
}); });
describe('router links', () => { describe('router links', () => {
fixmeIvy('FW-???: ASSERTION ERROR: The provided value must be an instance of an HTMLElement') &&
it('should support skipping location update for anchor router links', it('should support skipping location update for anchor router links',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp); const fixture = TestBed.createComponent(RootCmp);
@ -1522,6 +1557,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/team/22'); expect(location.path()).toEqual('/team/22');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should support string router links', fakeAsync(inject([Router], (router: Router) => { it('should support string router links', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -1529,7 +1565,8 @@ describe('Integration', () => {
path: 'team/:id', path: 'team/:id',
component: TeamCmp, component: TeamCmp,
children: [ children: [
{path: 'link', component: StringLinkCmp}, {path: 'simple', component: SimpleCmp} {path: 'link', component: StringLinkCmp},
{path: 'simple', component: SimpleCmp}
] ]
}]); }]);
@ -1662,7 +1699,9 @@ describe('Integration', () => {
expect(native.getAttribute('href')).toEqual('/home?a=123&q=456'); expect(native.getAttribute('href')).toEqual('/home?a=123&q=456');
})); }));
it('should support using links on non-a tags', fakeAsync(inject([Router], (router: Router) => { fixmeIvy('FW-???: assertion failures') &&
it('should support using links on non-a tags',
fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig([{ router.resetConfig([{
@ -1686,6 +1725,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should support absolute router links', fakeAsync(inject([Router], (router: Router) => { it('should support absolute router links', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -1693,7 +1733,8 @@ describe('Integration', () => {
path: 'team/:id', path: 'team/:id',
component: TeamCmp, component: TeamCmp,
children: [ children: [
{path: 'link', component: AbsoluteLinkCmp}, {path: 'simple', component: SimpleCmp} {path: 'link', component: AbsoluteLinkCmp},
{path: 'simple', component: SimpleCmp}
] ]
}]); }]);
@ -1709,6 +1750,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ simple, right: ]');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should support relative router links', fakeAsync(inject([Router], (router: Router) => { it('should support relative router links', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -1716,7 +1758,8 @@ describe('Integration', () => {
path: 'team/:id', path: 'team/:id',
component: TeamCmp, component: TeamCmp,
children: [ children: [
{path: 'link', component: RelativeLinkCmp}, {path: 'simple', component: SimpleCmp} {path: 'link', component: RelativeLinkCmp},
{path: 'simple', component: SimpleCmp}
] ]
}]); }]);
@ -1732,6 +1775,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 22 [ simple, right: ]'); expect(fixture.nativeElement).toHaveText('team 22 [ simple, right: ]');
}))); })));
fixmeIvy('FW-662: Components without selector are not supported') &&
it('should support top-level link', fakeAsync(inject([Router], (router: Router) => { it('should support top-level link', fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RelativeLinkInIfCmp); const fixture = createRoot(router, RelativeLinkInIfCmp);
advance(fixture); advance(fixture);
@ -1757,6 +1801,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('linksimple'); expect(fixture.nativeElement).toHaveText('linksimple');
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should support query params and fragments', it('should support query params and fragments',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -2035,7 +2080,9 @@ describe('Integration', () => {
}] }]
})); }));
it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fixmeIvy('FW-???: assertion failures') &&
it('works',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
router.resetConfig([ router.resetConfig([
{ {
path: '', path: '',
@ -2061,7 +2108,9 @@ describe('Integration', () => {
}] }]
})); }));
it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fixmeIvy('FW-???: assertion failures') &&
it('works',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const recordedEvents: any[] = []; const recordedEvents: any[] = [];
let cancelEvent: NavigationCancel = null !; let cancelEvent: NavigationCancel = null !;
router.events.forEach((e: any) => { router.events.forEach((e: any) => {
@ -2152,6 +2201,7 @@ describe('Integration', () => {
return fixture; return fixture;
} }
fixmeIvy('FW-???: TypeError: Cannot read property \'data\' of undefined') &&
it('should rerun guards and resolvers when params change', it('should rerun guards and resolvers when params change',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
const fixture = configureRouter(router, 'paramsChange'); const fixture = configureRouter(router, 'paramsChange');
@ -2179,6 +2229,7 @@ describe('Integration', () => {
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]); expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]);
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'data\' of undefined') &&
it('should rerun guards and resolvers when query params change', it('should rerun guards and resolvers when query params change',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
const fixture = configureRouter(router, 'paramsOrQueryParamsChange'); const fixture = configureRouter(router, 'paramsOrQueryParamsChange');
@ -2211,6 +2262,7 @@ describe('Integration', () => {
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]); expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]);
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'data\' of undefined') &&
it('should always rerun guards and resolvers', it('should always rerun guards and resolvers',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
const fixture = configureRouter(router, 'always'); const fixture = configureRouter(router, 'always');
@ -2240,10 +2292,14 @@ describe('Integration', () => {
router.navigateByUrl('/a;p=2(right:b)?q=1'); router.navigateByUrl('/a;p=2(right:b)?q=1');
advance(fixture); advance(fixture);
expect(guardRunCount).toEqual(5); expect(guardRunCount).toEqual(5);
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4}]); 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) => { 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 fixture = configureRouter(router, 'pathParamsChange');
const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance; const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance;
@ -2415,11 +2471,14 @@ describe('Integration', () => {
}); });
describe('should not deactivate a route when CanDeactivate returns false', () => { describe('should not deactivate a route when CanDeactivate returns false', () => {
it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('works',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig( router.resetConfig([
[{path: 'team/:id', component: TeamCmp, canDeactivate: ['CanDeactivateTeam']}]); {path: 'team/:id', component: TeamCmp, canDeactivate: ['CanDeactivateTeam']}
]);
router.navigateByUrl('/team/22'); router.navigateByUrl('/team/22');
advance(fixture); advance(fixture);
@ -2438,6 +2497,7 @@ describe('Integration', () => {
expect(canceledStatus).toEqual(false); expect(canceledStatus).toEqual(false);
}))); })));
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('works with componentless routes', it('works with componentless routes',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -2506,6 +2566,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/two-outlets/(a)'); expect(location.path()).toEqual('/two-outlets/(a)');
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('works with a nested route', it('works with a nested route',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -2514,8 +2575,11 @@ describe('Integration', () => {
path: 'team/:id', path: 'team/:id',
component: TeamCmp, component: TeamCmp,
children: [ children: [
{path: '', pathMatch: 'full', component: SimpleCmp}, {path: '', pathMatch: 'full', component: SimpleCmp}, {
{path: 'user/:name', component: UserCmp, canDeactivate: ['CanDeactivateUser']} path: 'user/:name',
component: UserCmp,
canDeactivate: ['CanDeactivateUser']
}
] ]
}]); }]);
@ -2537,6 +2601,7 @@ describe('Integration', () => {
}))); })));
}); });
fixmeIvy('FW-???: TypeError: Cannot read property \'componentInstance\' of undefined') &&
it('should not create a route state if navigation is canceled', it('should not create a route state if navigation is canceled',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -2644,6 +2709,7 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should pass next state as the 4 argument when guard is a class', it('should pass next state as the 4 argument when guard is a class',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -2661,13 +2727,16 @@ describe('Integration', () => {
expect(log).toEqual(['/team/22', '/team/33']); expect(log).toEqual(['/team/22', '/team/33']);
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should pass next state as the 4 argument when guard is a function', it('should pass next state as the 4 argument when guard is a function',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig([ router.resetConfig([{
{path: 'team/:id', component: TeamCmp, canDeactivate: ['FunctionWithNextState']} path: 'team/:id',
]); component: TeamCmp,
canDeactivate: ['FunctionWithNextState']
}]);
router.navigateByUrl('/team/22'); router.navigateByUrl('/team/22');
advance(fixture); advance(fixture);
@ -2691,7 +2760,9 @@ describe('Integration', () => {
beforeEach(() => { TestBed.configureTestingModule({providers: [AlwaysTrue]}); }); beforeEach(() => { TestBed.configureTestingModule({providers: [AlwaysTrue]}); });
it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('works',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig( router.resetConfig(
@ -2769,6 +2840,7 @@ describe('Integration', () => {
}))); })));
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should find the guard provided in lazy loaded module', it('should find the guard provided in lazy loaded module',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -2837,6 +2909,7 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not load children when CanLoad returns false', it('should not load children when CanLoad returns false',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -2848,8 +2921,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: imports: [RouterModule.forChild(
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])] [{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LoadedModule { class LoadedModule {
} }
@ -2941,6 +3014,7 @@ describe('Integration', () => {
// Regression where navigateByUrl with false CanLoad no longer resolved `false` value on // Regression where navigateByUrl with false CanLoad no longer resolved `false` value on
// navigateByUrl promise: https://github.com/angular/angular/issues/26284 // navigateByUrl promise: https://github.com/angular/angular/issues/26284
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should resolve navigateByUrl promise after CanLoad executes', it('should resolve navigateByUrl promise after CanLoad executes',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -2952,8 +3026,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: imports: [RouterModule.forChild(
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])] [{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LazyLoadedModule { class LazyLoadedModule {
} }
@ -2978,6 +3052,7 @@ describe('Integration', () => {
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should execute CanLoad only once', it('should execute CanLoad only once',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -2989,8 +3064,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: imports: [RouterModule.forChild(
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])] [{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LazyLoadedModule { class LazyLoadedModule {
} }
@ -2998,7 +3073,8 @@ describe('Integration', () => {
loader.stubbedModules = {lazy: LazyLoadedModule}; loader.stubbedModules = {lazy: LazyLoadedModule};
const fixture = createRoot(router, RootCmp); 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'); router.navigateByUrl('/lazy/loaded');
advance(fixture); advance(fixture);
@ -3050,9 +3126,11 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should call guards in the right order', it('should call guards in the right order',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, Logger], (router: Router, location: Location, logger: Logger) => { [Router, Location, Logger],
(router: Router, location: Location, logger: Logger) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig([{ router.resetConfig([{
@ -3079,9 +3157,11 @@ describe('Integration', () => {
]); ]);
}))); })));
fixmeIvy('FW-???: Error: ExpressionChangedAfterItHasBeenCheckedError') &&
it('should call deactivate guards from bottom to top', it('should call deactivate guards from bottom to top',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, Logger], (router: Router, location: Location, logger: Logger) => { [Router, Location, Logger],
(router: Router, location: Location, logger: Logger) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig([{ router.resetConfig([{
@ -3089,8 +3169,9 @@ describe('Integration', () => {
children: [{ children: [{
path: 'team/:id', path: 'team/:id',
canDeactivate: ['canDeactivate_team'], canDeactivate: ['canDeactivate_team'],
children: children: [
[{path: '', component: SimpleCmp, canDeactivate: ['canDeactivate_simple']}], {path: '', component: SimpleCmp, canDeactivate: ['canDeactivate_simple']}
],
component: TeamCmp component: TeamCmp
}] }]
}]); }]);
@ -3285,6 +3366,7 @@ describe('Integration', () => {
}))); })));
fixmeIvy('FW-662: Components without selector are not supported') &&
it('should expose an isActive property', fakeAsync(() => { it('should expose an isActive property', fakeAsync(() => {
@Component({ @Component({
template: `<a routerLink="/team" routerLinkActive #rla="routerLinkActive"></a> template: `<a routerLink="/team" routerLinkActive #rla="routerLinkActive"></a>
@ -3326,7 +3408,7 @@ describe('Integration', () => {
}); });
describe('lazy loading', () => { fixmeIvy('FW-561: Runtime compiler is not loaded') && describe('lazy loading', () => {
it('works', it('works',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3367,6 +3449,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should have 2 injector trees: module and element', it('should have 2 injector trees: module and element',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3456,6 +3539,7 @@ describe('Integration', () => {
}))); })));
// https://github.com/angular/angular/issues/12889 // https://github.com/angular/angular/issues/12889
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create a single instance of lazy-loaded modules', it('should create a single instance of lazy-loaded modules',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3494,6 +3578,7 @@ describe('Integration', () => {
}))); })));
// https://github.com/angular/angular/issues/13870 // https://github.com/angular/angular/issues/13870
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create a single instance of guards for lazy-loaded modules', it('should create a single instance of guards for lazy-loaded modules',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3539,12 +3624,13 @@ describe('Integration', () => {
advance(fixture); advance(fixture);
expect(fixture.nativeElement).toHaveText('lazy'); expect(fixture.nativeElement).toHaveText('lazy');
const lzc = const lzc = fixture.debugElement.query(By.directive(LazyLoadedComponent))
fixture.debugElement.query(By.directive(LazyLoadedComponent)).componentInstance; .componentInstance;
expect(lzc.injectedService).toBe(lzc.resolvedService); expect(lzc.injectedService).toBe(lzc.resolvedService);
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should emit RouteConfigLoadStart and RouteConfigLoadEnd event when route is lazy loaded', it('should emit RouteConfigLoadStart and RouteConfigLoadEnd event when route is lazy loaded',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3591,6 +3677,7 @@ describe('Integration', () => {
expect(events[1].toString()).toEqual('RouteConfigLoadEnd(path: lazy)'); expect(events[1].toString()).toEqual('RouteConfigLoadEnd(path: lazy)');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('throws an error when forRoot() is used in a lazy context', it('throws an error when forRoot() is used in a lazy context',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3601,7 +3688,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: [RouterModule.forRoot([{path: 'loaded', component: LazyLoadedComponent}])] imports:
[RouterModule.forRoot([{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LoadedModule { class LoadedModule {
} }
@ -3620,6 +3708,7 @@ describe('Integration', () => {
`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`); `RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should combine routes from multiple modules into a single configuration', it('should combine routes from multiple modules into a single configuration',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3649,7 +3738,10 @@ describe('Integration', () => {
class LoadedModule { class LoadedModule {
} }
loader.stubbedModules = {expected1: LoadedModule, expected2: SiblingOfLoadedModule}; loader.stubbedModules = {
expected1: LoadedModule,
expected2: SiblingOfLoadedModule
};
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -3667,9 +3759,11 @@ describe('Integration', () => {
expect(location.path()).toEqual('/lazy2/loaded'); expect(location.path()).toEqual('/lazy2/loaded');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should allow lazy loaded module in named outlet', it('should allow lazy loaded module in named outlet',
fakeAsync(inject( fakeAsync(inject(
[Router, NgModuleFactoryLoader], (router: Router, loader: SpyNgModuleFactoryLoader) => { [Router, NgModuleFactoryLoader],
(router: Router, loader: SpyNgModuleFactoryLoader) => {
@Component({selector: 'lazy', template: 'lazy-loaded'}) @Component({selector: 'lazy', template: 'lazy-loaded'})
class LazyComponent { class LazyComponent {
@ -3704,7 +3798,8 @@ describe('Integration', () => {
router.navigateByUrl('/team/22/(user/john//right:lazy)'); router.navigateByUrl('/team/22/(user/john//right:lazy)');
advance(fixture); 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', it('should allow componentless named outlet to render children',
@ -3793,6 +3888,7 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should use the injector of the lazily-loaded configuration', it('should use the injector of the lazily-loaded configuration',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3815,6 +3911,7 @@ describe('Integration', () => {
}))); })));
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('works when given a callback', it('works when given a callback',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], (router: Router, location: Location) => { [Router, Location, NgModuleFactoryLoader], (router: Router, location: Location) => {
@ -3824,7 +3921,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])], imports:
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])],
}) })
class LoadedModule { class LoadedModule {
} }
@ -3864,6 +3962,7 @@ describe('Integration', () => {
]); ]);
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work with complex redirect rules', it('should work with complex redirect rules',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3874,7 +3973,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])], imports:
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])],
}) })
class LoadedModule { class LoadedModule {
} }
@ -3891,6 +3991,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/lazy/loaded'); expect(location.path()).toEqual('/lazy/loaded');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work with wildcard route', it('should work with wildcard route',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3926,6 +4027,7 @@ describe('Integration', () => {
preloader.setUpPreloading(); preloader.setUpPreloading();
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3943,8 +4045,8 @@ describe('Integration', () => {
} }
@NgModule({ @NgModule({
imports: imports: [RouterModule.forChild(
[RouterModule.forChild([{path: 'LoadedModule1', loadChildren: 'expected2'}])] [{path: 'LoadedModule1', loadChildren: 'expected2'}])]
}) })
class LoadedModule1 { class LoadedModule1 {
} }
@ -3954,7 +4056,8 @@ describe('Integration', () => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig([ router.resetConfig([
{path: 'blank', component: BlankCmp}, {path: 'lazy', loadChildren: 'expected'} {path: 'blank', component: BlankCmp},
{path: 'lazy', loadChildren: 'expected'}
]); ]);
router.navigateByUrl('/blank'); router.navigateByUrl('/blank');
@ -4135,6 +4238,7 @@ describe('Integration', () => {
class LazyLoadedModule { class LazyLoadedModule {
} }
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not ignore empty path when in legacy mode', it('should not ignore empty path when in legacy mode',
fakeAsync(inject( fakeAsync(inject(
[Router, NgModuleFactoryLoader], [Router, NgModuleFactoryLoader],
@ -4153,6 +4257,7 @@ describe('Integration', () => {
expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple'); expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should ignore empty path when in corrected mode', it('should ignore empty path when in corrected mode',
fakeAsync(inject( fakeAsync(inject(
[Router, NgModuleFactoryLoader], [Router, NgModuleFactoryLoader],
@ -4216,6 +4321,7 @@ describe('Integration', () => {
} }
} }
fixmeIvy('FW-???: assertion failures') &&
it('should support attaching & detaching fragments', it('should support attaching & detaching fragments',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -4258,6 +4364,7 @@ describe('Integration', () => {
expect(teamCmp.route.firstChild.snapshot.params).toEqual({p: '2'}); expect(teamCmp.route.firstChild.snapshot.params).toEqual({p: '2'});
}))); })));
fixmeIvy('FW-???: assertion failures') &&
it('should support shorter lifecycles', it('should support shorter lifecycles',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -4277,6 +4384,7 @@ describe('Integration', () => {
expect(simpleCmp1).not.toBe(simpleCmp2); expect(simpleCmp1).not.toBe(simpleCmp2);
}))); })));
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', it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation',
fakeAsync(() => { fakeAsync(() => {
@Component({ @Component({

View File

@ -8,6 +8,7 @@
import {TestBed} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {Observable, Observer, of } from 'rxjs'; import {Observable, Observer, of } from 'rxjs';
import {every, mergeMap} from 'rxjs/operators'; import {every, mergeMap} from 'rxjs/operators';
import {TestScheduler} from 'rxjs/testing'; import {TestScheduler} from 'rxjs/testing';
@ -15,7 +16,6 @@ import {TestScheduler} from 'rxjs/testing';
import {prioritizedGuardValue} from '../../src/operators/prioritized_guard_value'; import {prioritizedGuardValue} from '../../src/operators/prioritized_guard_value';
import {Router} from '../../src/router'; import {Router} from '../../src/router';
import {UrlTree} from '../../src/url_tree'; import {UrlTree} from '../../src/url_tree';
import {RouterTestingModule} from '../../testing/src/router_testing_module';
describe('prioritizedGuardValue operator', () => { describe('prioritizedGuardValue operator', () => {

View File

@ -9,13 +9,14 @@
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Component, ContentChild, NgModule, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; import {Component, ContentChild, NgModule, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing'; 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 {Router} from '@angular/router';
import {RouterTestingModule} from '@angular/router/testing'; import {RouterTestingModule} from '@angular/router/testing';
describe('Integration', () => { describe('Integration', () => {
describe('routerLinkActive', () => { describe('routerLinkActive', () => {
fixmeIvy('FW-662: Components without selector are not supported') &&
it('should not cause infinite loops in the change detection - #15825', fakeAsync(() => { it('should not cause infinite loops in the change detection - #15825', fakeAsync(() => {
@Component({selector: 'simple', template: 'simple'}) @Component({selector: 'simple', template: 'simple'})
class SimpleCmp { class SimpleCmp {
@ -58,6 +59,7 @@ describe('Integration', () => {
expect(() => advance(fixture)).not.toThrow(); expect(() => advance(fixture)).not.toThrow();
})); }));
fixmeIvy('FW-662: Components without selector are not supported') &&
it('should set isActive right after looking at its children -- #18983', fakeAsync(() => { it('should set isActive right after looking at its children -- #18983', fakeAsync(() => {
@Component({ @Component({
template: ` template: `

View File

@ -8,6 +8,7 @@
import {Location} from '@angular/common'; import {Location} from '@angular/common';
import {TestBed, inject} from '@angular/core/testing'; import {TestBed, inject} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {of } from 'rxjs'; import {of } from 'rxjs';
import {Routes} from '../src/config'; import {Routes} from '../src/config';
@ -20,7 +21,6 @@ import {RouterStateSnapshot, createEmptyStateSnapshot} from '../src/router_state
import {DefaultUrlSerializer, UrlTree} from '../src/url_tree'; import {DefaultUrlSerializer, UrlTree} from '../src/url_tree';
import {getAllRouteGuards} from '../src/utils/preactivation'; import {getAllRouteGuards} from '../src/utils/preactivation';
import {TreeNode} from '../src/utils/tree'; import {TreeNode} from '../src/utils/tree';
import {RouterTestingModule} from '../testing/src/router_testing_module';
import {Logger, createActivatedRouteSnapshot, provideTokenLogger} from './helpers'; import {Logger, createActivatedRouteSnapshot, provideTokenLogger} from './helpers';

View File

@ -8,10 +8,11 @@
import {Compiler, Component, NgModule, NgModuleFactoryLoader, NgModuleRef} from '@angular/core'; import {Compiler, Component, NgModule, NgModuleFactoryLoader, NgModuleRef} from '@angular/core';
import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing'; 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 {Route, RouteConfigLoadEnd, RouteConfigLoadStart, Router, RouterModule} from '../index';
import {LoadedRouterConfig} from '../src/config'; import {LoadedRouterConfig} from '../src/config';
import {PreloadAllModules, PreloadingStrategy, RouterPreloader} from '../src/router_preloader';
import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing'; import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
describe('RouterPreloader', () => { describe('RouterPreloader', () => {
@ -35,6 +36,7 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router], [NgModuleFactoryLoader, RouterPreloader, Router],
@ -58,6 +60,7 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef],
@ -66,15 +69,15 @@ describe('RouterPreloader', () => {
const events: Array<RouteConfigLoadStart|RouteConfigLoadEnd> = []; const events: Array<RouteConfigLoadStart|RouteConfigLoadEnd> = [];
@NgModule({ @NgModule({
declarations: [LazyLoadedCmp], declarations: [LazyLoadedCmp],
imports: imports: [RouterModule.forChild(
[RouterModule.forChild([{path: 'LoadedModule2', component: LazyLoadedCmp}])] [{path: 'LoadedModule2', component: LazyLoadedCmp}])]
}) })
class LoadedModule2 { class LoadedModule2 {
} }
@NgModule({ @NgModule({
imports: imports: [RouterModule.forChild(
[RouterModule.forChild([{path: 'LoadedModule1', loadChildren: 'expected2'}])] [{path: 'LoadedModule1', loadChildren: 'expected2'}])]
}) })
class LoadedModule1 { class LoadedModule1 {
} }
@ -125,10 +128,12 @@ describe('RouterPreloader', () => {
}); });
}); });
it('should work', fakeAsync(inject( fixmeIvy('FW-???: Cannot read property \'declarations\' of undefined') &&
it('should work',
fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler], [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler],
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router,
router: Router, testModule: NgModuleRef<any>, compiler: Compiler) => { testModule: NgModuleRef<any>, compiler: Compiler) => {
@NgModule() @NgModule()
class LoadedModule2 { class LoadedModule2 {
} }
@ -195,6 +200,7 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router], [NgModuleFactoryLoader, RouterPreloader, Router],
@ -224,6 +230,7 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router], [NgModuleFactoryLoader, RouterPreloader, Router],

View File

@ -7,7 +7,7 @@
*/ */
import {fakeAsync, tick} from '@angular/core/testing'; import {fakeAsync, tick} from '@angular/core/testing';
import {SpyNgModuleFactoryLoader} from '../testing/src/router_testing_module'; import {SpyNgModuleFactoryLoader} from '@angular/router/testing';
describe('SpyNgModuleFactoryLoader', () => { describe('SpyNgModuleFactoryLoader', () => {
it('should invoke the compiler when the setter is called', () => { it('should invoke the compiler when the setter is called', () => {