@ -8,17 +8,19 @@
|
||||
|
||||
import {NgModuleRef} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {Observable, of } from 'rxjs';
|
||||
import {Observable, of} from 'rxjs';
|
||||
|
||||
import {applyRedirects} from '../src/apply_redirects';
|
||||
import {LoadedRouterConfig, Route, Routes} from '../src/config';
|
||||
import {DefaultUrlSerializer, UrlSegment, UrlSegmentGroup, UrlTree, equalSegments} from '../src/url_tree';
|
||||
import {DefaultUrlSerializer, equalSegments, UrlSegment, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
||||
|
||||
describe('applyRedirects', () => {
|
||||
const serializer = new DefaultUrlSerializer();
|
||||
let testModule: NgModuleRef<any>;
|
||||
|
||||
beforeEach(() => { testModule = TestBed.inject(NgModuleRef); });
|
||||
beforeEach(() => {
|
||||
testModule = TestBed.inject(NgModuleRef);
|
||||
});
|
||||
|
||||
it('should return the same url tree when no redirects', () => {
|
||||
checkRedirect(
|
||||
@ -31,13 +33,17 @@ describe('applyRedirects', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
'/a/b', (t: UrlTree) => { expectTreeToBe(t, '/a/b'); });
|
||||
'/a/b', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/a/b');
|
||||
});
|
||||
});
|
||||
|
||||
it('should add new segments when needed', () => {
|
||||
checkRedirect(
|
||||
[{path: 'a/b', redirectTo: 'a/b/c'}, {path: '**', component: ComponentC}], '/a/b',
|
||||
(t: UrlTree) => { expectTreeToBe(t, '/a/b/c'); });
|
||||
(t: UrlTree) => {
|
||||
expectTreeToBe(t, '/a/b/c');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support redirecting with to an URL with query parameters', () => {
|
||||
@ -57,11 +63,13 @@ describe('applyRedirects', () => {
|
||||
{path: 'a/:aid/b/:bid', redirectTo: 'newa/:aid/newb/:bid'},
|
||||
{path: '**', component: ComponentC}
|
||||
],
|
||||
'/a/1/b/2', (t: UrlTree) => { expectTreeToBe(t, '/newa/1/newb/2'); });
|
||||
'/a/1/b/2', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/newa/1/newb/2');
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when cannot handle a positional parameter', () => {
|
||||
applyRedirects(testModule.injector, null !, serializer, tree('/a/1'), [
|
||||
applyRedirects(testModule.injector, null!, serializer, tree('/a/1'), [
|
||||
{path: 'a/:id', redirectTo: 'a/:other'}
|
||||
]).subscribe(() => {}, (e) => {
|
||||
expect(e.message).toEqual('Cannot redirect to \'a/:other\'. Cannot find \':other\'.');
|
||||
@ -71,7 +79,9 @@ describe('applyRedirects', () => {
|
||||
it('should pass matrix parameters', () => {
|
||||
checkRedirect(
|
||||
[{path: 'a/:id', redirectTo: 'd/a/:id/e'}, {path: '**', component: ComponentC}],
|
||||
'/a;p1=1/1;p2=2', (t: UrlTree) => { expectTreeToBe(t, '/d/a;p1=1/1;p2=2/e'); });
|
||||
'/a;p1=1/1;p2=2', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/d/a;p1=1/1;p2=2/e');
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle preserve secondary routes', () => {
|
||||
@ -80,7 +90,9 @@ describe('applyRedirects', () => {
|
||||
{path: 'a/:id', redirectTo: 'd/a/:id/e'},
|
||||
{path: 'c/d', component: ComponentA, outlet: 'aux'}, {path: '**', component: ComponentC}
|
||||
],
|
||||
'/a/1(aux:c/d)', (t: UrlTree) => { expectTreeToBe(t, '/d/a/1/e(aux:c/d)'); });
|
||||
'/a/1(aux:c/d)', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/d/a/1/e(aux:c/d)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should redirect secondary routes', () => {
|
||||
@ -90,7 +102,9 @@ describe('applyRedirects', () => {
|
||||
{path: 'c/d', redirectTo: 'f/c/d/e', outlet: 'aux'},
|
||||
{path: '**', component: ComponentC, outlet: 'aux'}
|
||||
],
|
||||
'/a/1(aux:c/d)', (t: UrlTree) => { expectTreeToBe(t, '/a/1(aux:f/c/d/e)'); });
|
||||
'/a/1(aux:c/d)', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/a/1(aux:f/c/d/e)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the configuration of the route redirected to', () => {
|
||||
@ -105,7 +119,9 @@ describe('applyRedirects', () => {
|
||||
},
|
||||
{path: 'c', redirectTo: 'a'}
|
||||
],
|
||||
'c/b', (t: UrlTree) => { expectTreeToBe(t, 'a/b'); });
|
||||
'c/b', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/b');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support redirects with both main and aux', () => {
|
||||
@ -119,7 +135,9 @@ describe('applyRedirects', () => {
|
||||
{path: 'b', redirectTo: 'cc', outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/(b//aux:b)', (t: UrlTree) => { expectTreeToBe(t, 'a/(bb//aux:cc)'); });
|
||||
'a/(b//aux:b)', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(bb//aux:cc)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support redirects with both main and aux (with a nested redirect)', () => {
|
||||
@ -138,7 +156,9 @@ describe('applyRedirects', () => {
|
||||
{path: 'b', redirectTo: 'cc/d', outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/(b//aux:b)', (t: UrlTree) => { expectTreeToBe(t, 'a/(bb//aux:cc/dd)'); });
|
||||
'a/(b//aux:b)', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(bb//aux:cc/dd)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should redirect wild cards', () => {
|
||||
@ -147,7 +167,9 @@ describe('applyRedirects', () => {
|
||||
{path: '404', component: ComponentA},
|
||||
{path: '**', redirectTo: '/404'},
|
||||
],
|
||||
'/a/1(aux:c/d)', (t: UrlTree) => { expectTreeToBe(t, '/404'); });
|
||||
'/a/1(aux:c/d)', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/404');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support absolute redirects', () => {
|
||||
@ -160,7 +182,9 @@ describe('applyRedirects', () => {
|
||||
},
|
||||
{path: '**', component: ComponentC}
|
||||
],
|
||||
'/a/b/1?b=2', (t: UrlTree) => { expectTreeToBe(t, '/absolute/1?a=1&b=2#f1'); });
|
||||
'/a/b/1?b=2', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/absolute/1?a=1&b=2#f1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('lazy loading', () => {
|
||||
@ -169,7 +193,7 @@ describe('applyRedirects', () => {
|
||||
const loader = {
|
||||
load: (injector: any, p: any) => {
|
||||
if (injector !== testModule.injector) throw 'Invalid Injector';
|
||||
return of (loadedConfig);
|
||||
return of(loadedConfig);
|
||||
}
|
||||
};
|
||||
const config: Routes = [{path: 'a', component: ComponentA, loadChildren: 'children'}];
|
||||
@ -188,24 +212,23 @@ describe('applyRedirects', () => {
|
||||
const config = [{path: 'a', component: ComponentA, loadChildren: 'children'}];
|
||||
|
||||
applyRedirects(testModule.injector, <any>loader, serializer, tree('a/b'), config)
|
||||
.subscribe(() => {}, (e) => { expect(e.message).toEqual('Loading Error'); });
|
||||
.subscribe(() => {}, (e) => {
|
||||
expect(e.message).toEqual('Loading Error');
|
||||
});
|
||||
});
|
||||
|
||||
it('should load when all canLoad guards return true', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: 'b', component: ComponentB}], testModule);
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const guard = () => true;
|
||||
const injector = {
|
||||
get: (token: any) => token === 'guard1' || token === 'guard2' ? guard : {injector}
|
||||
};
|
||||
|
||||
const config = [{
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
canLoad: ['guard1', 'guard2'],
|
||||
loadChildren: 'children'
|
||||
}];
|
||||
const config = [
|
||||
{path: 'a', component: ComponentA, canLoad: ['guard1', 'guard2'], loadChildren: 'children'}
|
||||
];
|
||||
|
||||
applyRedirects(<any>injector, <any>loader, serializer, tree('a/b'), config).forEach(r => {
|
||||
expectTreeToBe(r, '/a/b');
|
||||
@ -214,7 +237,7 @@ describe('applyRedirects', () => {
|
||||
|
||||
it('should not load when any canLoad guards return false', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: 'b', component: ComponentB}], testModule);
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const trueGuard = () => true;
|
||||
const falseGuard = () => false;
|
||||
@ -231,16 +254,15 @@ describe('applyRedirects', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const config = [{
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
canLoad: ['guard1', 'guard2'],
|
||||
loadChildren: 'children'
|
||||
}];
|
||||
const config = [
|
||||
{path: 'a', component: ComponentA, canLoad: ['guard1', 'guard2'], loadChildren: 'children'}
|
||||
];
|
||||
|
||||
applyRedirects(<any>injector, <any>loader, serializer, tree('a/b'), config)
|
||||
.subscribe(
|
||||
() => { throw 'Should not reach'; },
|
||||
() => {
|
||||
throw 'Should not reach';
|
||||
},
|
||||
(e) => {
|
||||
expect(e.message).toEqual(
|
||||
`NavigationCancelingError: Cannot load children because the guard of the route "path: 'a'" returned false`);
|
||||
@ -249,7 +271,7 @@ describe('applyRedirects', () => {
|
||||
|
||||
it('should not load when any canLoad guards is rejected (promises)', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: 'b', component: ComponentB}], testModule);
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const trueGuard = () => Promise.resolve(true);
|
||||
const falseGuard = () => Promise.reject('someError');
|
||||
@ -266,21 +288,23 @@ describe('applyRedirects', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const config = [{
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
canLoad: ['guard1', 'guard2'],
|
||||
loadChildren: 'children'
|
||||
}];
|
||||
const config = [
|
||||
{path: 'a', component: ComponentA, canLoad: ['guard1', 'guard2'], loadChildren: 'children'}
|
||||
];
|
||||
|
||||
applyRedirects(<any>injector, <any>loader, serializer, tree('a/b'), config)
|
||||
.subscribe(
|
||||
() => { throw 'Should not reach'; }, (e) => { expect(e).toEqual('someError'); });
|
||||
() => {
|
||||
throw 'Should not reach';
|
||||
},
|
||||
(e) => {
|
||||
expect(e).toEqual('someError');
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with objects implementing the CanLoad interface', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: 'b', component: ComponentB}], testModule);
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const guard = {canLoad: () => Promise.resolve(true)};
|
||||
const injector = {get: (token: any) => token === 'guard' ? guard : {injector}};
|
||||
@ -289,13 +313,18 @@ describe('applyRedirects', () => {
|
||||
[{path: 'a', component: ComponentA, canLoad: ['guard'], loadChildren: 'children'}];
|
||||
|
||||
applyRedirects(<any>injector, <any>loader, serializer, tree('a/b'), config)
|
||||
.subscribe((r) => { expectTreeToBe(r, '/a/b'); }, (e) => { throw 'Should not reach'; });
|
||||
|
||||
.subscribe(
|
||||
(r) => {
|
||||
expectTreeToBe(r, '/a/b');
|
||||
},
|
||||
(e) => {
|
||||
throw 'Should not reach';
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass UrlSegments to functions implementing the canLoad guard interface', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: 'b', component: ComponentB}], testModule);
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
let passedUrlSegments: UrlSegment[];
|
||||
|
||||
@ -316,13 +345,14 @@ describe('applyRedirects', () => {
|
||||
expect(passedUrlSegments[0].path).toBe('a');
|
||||
expect(passedUrlSegments[1].path).toBe('b');
|
||||
},
|
||||
(e) => { throw 'Should not reach'; });
|
||||
|
||||
(e) => {
|
||||
throw 'Should not reach';
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass UrlSegments to objects implementing the canLoad guard interface', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: 'b', component: ComponentB}], testModule);
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
let passedUrlSegments: UrlSegment[];
|
||||
|
||||
@ -345,14 +375,15 @@ describe('applyRedirects', () => {
|
||||
expect(passedUrlSegments[0].path).toBe('a');
|
||||
expect(passedUrlSegments[1].path).toBe('b');
|
||||
},
|
||||
(e) => { throw 'Should not reach'; });
|
||||
|
||||
(e) => {
|
||||
throw 'Should not reach';
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with absolute redirects', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: '', component: ComponentB}], testModule);
|
||||
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const config: Routes =
|
||||
[{path: '', pathMatch: 'full', redirectTo: '/a'}, {path: 'a', loadChildren: 'children'}];
|
||||
@ -371,7 +402,7 @@ describe('applyRedirects', () => {
|
||||
load: (injector: any, p: any) => {
|
||||
if (called) throw new Error('Should not be called twice');
|
||||
called = true;
|
||||
return of (loadedConfig);
|
||||
return of(loadedConfig);
|
||||
}
|
||||
};
|
||||
|
||||
@ -386,42 +417,50 @@ describe('applyRedirects', () => {
|
||||
expectTreeToBe(r, 'a?k2');
|
||||
expect((config[0] as any)._loadedConfig).toBe(loadedConfig);
|
||||
},
|
||||
(e) => { throw 'Should not reach'; });
|
||||
(e) => {
|
||||
throw 'Should not reach';
|
||||
});
|
||||
});
|
||||
|
||||
it('should load the configuration of a wildcard route', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: '', component: ComponentB}], testModule);
|
||||
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const config: Routes = [{path: '**', loadChildren: 'children'}];
|
||||
|
||||
applyRedirects(testModule.injector, <any>loader, serializer, tree('xyz'), config)
|
||||
.forEach(r => { expect((config[0] as any)._loadedConfig).toBe(loadedConfig); });
|
||||
.forEach(r => {
|
||||
expect((config[0] as any)._loadedConfig).toBe(loadedConfig);
|
||||
});
|
||||
});
|
||||
|
||||
it('should load the configuration after a local redirect from a wildcard route', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: '', component: ComponentB}], testModule);
|
||||
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const config: Routes =
|
||||
[{path: 'not-found', loadChildren: 'children'}, {path: '**', redirectTo: 'not-found'}];
|
||||
|
||||
applyRedirects(testModule.injector, <any>loader, serializer, tree('xyz'), config)
|
||||
.forEach(r => { expect((config[0] as any)._loadedConfig).toBe(loadedConfig); });
|
||||
.forEach(r => {
|
||||
expect((config[0] as any)._loadedConfig).toBe(loadedConfig);
|
||||
});
|
||||
});
|
||||
|
||||
it('should load the configuration after an absolute redirect from a wildcard route', () => {
|
||||
const loadedConfig = new LoadedRouterConfig([{path: '', component: ComponentB}], testModule);
|
||||
|
||||
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
|
||||
const loader = {load: (injector: any, p: any) => of(loadedConfig)};
|
||||
|
||||
const config: Routes =
|
||||
[{path: 'not-found', loadChildren: 'children'}, {path: '**', redirectTo: '/not-found'}];
|
||||
|
||||
applyRedirects(testModule.injector, <any>loader, serializer, tree('xyz'), config)
|
||||
.forEach(r => { expect((config[0] as any)._loadedConfig).toBe(loadedConfig); });
|
||||
.forEach(r => {
|
||||
expect((config[0] as any)._loadedConfig).toBe(loadedConfig);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -438,7 +477,9 @@ describe('applyRedirects', () => {
|
||||
},
|
||||
{path: '', redirectTo: 'a'}
|
||||
],
|
||||
'b', (t: UrlTree) => { expectTreeToBe(t, 'a/b'); });
|
||||
'b', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/b');
|
||||
});
|
||||
});
|
||||
|
||||
it('redirect from an empty path should work (absolute redirect)', () => {
|
||||
@ -453,7 +494,9 @@ describe('applyRedirects', () => {
|
||||
},
|
||||
{path: '', redirectTo: '/a/b'}
|
||||
],
|
||||
'', (t: UrlTree) => { expectTreeToBe(t, 'a/b'); });
|
||||
'', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/b');
|
||||
});
|
||||
});
|
||||
|
||||
it('should redirect empty path route only when terminal', () => {
|
||||
@ -468,10 +511,14 @@ describe('applyRedirects', () => {
|
||||
{path: '', redirectTo: 'a', pathMatch: 'full'}
|
||||
];
|
||||
|
||||
applyRedirects(testModule.injector, null !, serializer, tree('b'), config)
|
||||
applyRedirects(testModule.injector, null!, serializer, tree('b'), config)
|
||||
.subscribe(
|
||||
(_) => { throw 'Should not be reached'; },
|
||||
e => { expect(e.message).toEqual('Cannot match any routes. URL Segment: \'b\''); });
|
||||
(_) => {
|
||||
throw 'Should not be reached';
|
||||
},
|
||||
e => {
|
||||
expect(e.message).toEqual('Cannot match any routes. URL Segment: \'b\'');
|
||||
});
|
||||
});
|
||||
|
||||
it('redirect from an empty path should work (nested case)', () => {
|
||||
@ -484,7 +531,9 @@ describe('applyRedirects', () => {
|
||||
},
|
||||
{path: '', redirectTo: 'a'}
|
||||
],
|
||||
'', (t: UrlTree) => { expectTreeToBe(t, 'a/b'); });
|
||||
'', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/b');
|
||||
});
|
||||
});
|
||||
|
||||
it('redirect to an empty path should work', () => {
|
||||
@ -493,7 +542,9 @@ describe('applyRedirects', () => {
|
||||
{path: '', component: ComponentA, children: [{path: 'b', component: ComponentB}]},
|
||||
{path: 'a', redirectTo: ''}
|
||||
],
|
||||
'a/b', (t: UrlTree) => { expectTreeToBe(t, 'b'); });
|
||||
'a/b', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'b');
|
||||
});
|
||||
});
|
||||
|
||||
describe('aux split is in the middle', () => {
|
||||
@ -507,7 +558,9 @@ describe('applyRedirects', () => {
|
||||
{path: '', redirectTo: 'c', outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/b', (t: UrlTree) => { expectTreeToBe(t, 'a/(b//aux:c)'); });
|
||||
'a/b', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(b//aux:c)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a new url segment (terminal)', () => {
|
||||
@ -520,7 +573,9 @@ describe('applyRedirects', () => {
|
||||
{path: '', pathMatch: 'full', redirectTo: 'c', outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/b', (t: UrlTree) => { expectTreeToBe(t, 'a/b'); });
|
||||
'a/b', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/b');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -535,7 +590,9 @@ describe('applyRedirects', () => {
|
||||
{path: '', redirectTo: 'c', outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a', (t: UrlTree) => { expectTreeToBe(t, 'a/(b//aux:c)'); });
|
||||
'a', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(b//aux:c)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a new child (terminal)', () => {
|
||||
@ -548,7 +605,9 @@ describe('applyRedirects', () => {
|
||||
{path: '', pathMatch: 'full', redirectTo: 'c', outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a', (t: UrlTree) => { expectTreeToBe(t, 'a/(b//aux:c)'); });
|
||||
'a', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(b//aux:c)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should work only only primary outlet', () => {
|
||||
@ -560,7 +619,9 @@ describe('applyRedirects', () => {
|
||||
{path: 'c', component: ComponentC, outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/(aux:c)', (t: UrlTree) => { expectTreeToBe(t, 'a/(b//aux:c)'); });
|
||||
'a/(aux:c)', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(b//aux:c)');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -580,7 +641,9 @@ describe('applyRedirects', () => {
|
||||
{path: '', redirectTo: 'c', outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/(d//aux:e)', (t: UrlTree) => { expectTreeToBe(t, 'a/(b/d//aux:c/e)'); });
|
||||
'a/(d//aux:e)', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(b/d//aux:c/e)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not create a new child (terminal)', () => {
|
||||
@ -598,10 +661,14 @@ describe('applyRedirects', () => {
|
||||
]
|
||||
}];
|
||||
|
||||
applyRedirects(testModule.injector, null !, serializer, tree('a/(d//aux:e)'), config)
|
||||
applyRedirects(testModule.injector, null!, serializer, tree('a/(d//aux:e)'), config)
|
||||
.subscribe(
|
||||
(_) => { throw 'Should not be reached'; },
|
||||
e => { expect(e.message).toEqual('Cannot match any routes. URL Segment: \'a\''); });
|
||||
(_) => {
|
||||
throw 'Should not be reached';
|
||||
},
|
||||
e => {
|
||||
expect(e.message).toEqual('Cannot match any routes. URL Segment: \'a\'');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -610,7 +677,9 @@ describe('applyRedirects', () => {
|
||||
it('should not error when no children matching and no url is left', () => {
|
||||
checkRedirect(
|
||||
[{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]}],
|
||||
'/a', (t: UrlTree) => { expectTreeToBe(t, 'a'); });
|
||||
'/a', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not error when no children matching and no url is left (aux routes)', () => {
|
||||
@ -624,16 +693,22 @@ describe('applyRedirects', () => {
|
||||
{path: 'c', component: ComponentC, outlet: 'aux'},
|
||||
]
|
||||
}],
|
||||
'/a', (t: UrlTree) => { expectTreeToBe(t, 'a/(aux:c)'); });
|
||||
'/a', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/(aux:c)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should error when no children matching and some url is left', () => {
|
||||
applyRedirects(
|
||||
testModule.injector, null !, serializer, tree('/a/c'),
|
||||
testModule.injector, null!, serializer, tree('/a/c'),
|
||||
[{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]}])
|
||||
.subscribe(
|
||||
(_) => { throw 'Should not be reached'; },
|
||||
e => { expect(e.message).toEqual('Cannot match any routes. URL Segment: \'a/c\''); });
|
||||
(_) => {
|
||||
throw 'Should not be reached';
|
||||
},
|
||||
e => {
|
||||
expect(e.message).toEqual('Cannot match any routes. URL Segment: \'a/c\'');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -653,7 +728,9 @@ describe('applyRedirects', () => {
|
||||
component: ComponentA,
|
||||
children: [{path: 'b', component: ComponentB}]
|
||||
}] as any,
|
||||
'/a/1/b', (t: UrlTree) => { expectTreeToBe(t, 'a/1/b'); });
|
||||
'/a/1/b', (t: UrlTree) => {
|
||||
expectTreeToBe(t, 'a/1/b');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -665,7 +742,9 @@ describe('applyRedirects', () => {
|
||||
{path: 'b/:id', component: ComponentB},
|
||||
{path: 'c/:id', component: ComponentC, outlet: 'aux'}
|
||||
],
|
||||
'a/1;p=99', (t: UrlTree) => { expectTreeToBe(t, '/b/1;p=99(aux:c/1;p=99)'); });
|
||||
'a/1;p=99', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/b/1;p=99(aux:c/1;p=99)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should work when using absolute redirects (wildcard)', () => {
|
||||
@ -674,17 +753,21 @@ describe('applyRedirects', () => {
|
||||
{path: '**', redirectTo: '/b(aux:c)'}, {path: 'b', component: ComponentB},
|
||||
{path: 'c', component: ComponentC, outlet: 'aux'}
|
||||
],
|
||||
'a/1', (t: UrlTree) => { expectTreeToBe(t, '/b(aux:c)'); });
|
||||
'a/1', (t: UrlTree) => {
|
||||
expectTreeToBe(t, '/b(aux:c)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when using non-absolute redirects', () => {
|
||||
applyRedirects(
|
||||
testModule.injector, null !, serializer, tree('a'),
|
||||
testModule.injector, null!, serializer, tree('a'),
|
||||
[
|
||||
{path: 'a', redirectTo: 'b(aux:c)'},
|
||||
])
|
||||
.subscribe(
|
||||
() => { throw new Error('should not be reached'); },
|
||||
() => {
|
||||
throw new Error('should not be reached');
|
||||
},
|
||||
(e) => {
|
||||
expect(e.message).toEqual(
|
||||
'Only absolute redirects can have named outlets. redirectTo: \'b(aux:c)\'');
|
||||
@ -694,8 +777,10 @@ describe('applyRedirects', () => {
|
||||
});
|
||||
|
||||
function checkRedirect(config: Routes, url: string, callback: any): void {
|
||||
applyRedirects(TestBed, null !, new DefaultUrlSerializer(), tree(url), config)
|
||||
.subscribe(callback, e => { throw e; });
|
||||
applyRedirects(TestBed, null!, new DefaultUrlSerializer(), tree(url), config)
|
||||
.subscribe(callback, e => {
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
function tree(url: string): UrlTree {
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {APP_BASE_HREF, DOCUMENT, Location, ɵgetDOM as getDOM} from '@angular/common';
|
||||
import {ApplicationRef, CUSTOM_ELEMENTS_SCHEMA, Component, NgModule, destroyPlatform} from '@angular/core';
|
||||
import {ApplicationRef, Component, CUSTOM_ELEMENTS_SCHEMA, destroyPlatform, NgModule} from '@angular/core';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
@ -17,11 +17,13 @@ import {filter, first} from 'rxjs/operators';
|
||||
describe('bootstrap', () => {
|
||||
if (isNode) return;
|
||||
let log: any[] = [];
|
||||
let testProviders: any[] = null !;
|
||||
let testProviders: any[] = null!;
|
||||
|
||||
@Component({selector: 'test-app', template: 'root <router-outlet></router-outlet>'})
|
||||
class RootCmp {
|
||||
constructor() { log.push('RootCmp'); }
|
||||
constructor() {
|
||||
log.push('RootCmp');
|
||||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'test-app2', template: 'root <router-outlet></router-outlet>'})
|
||||
@ -63,9 +65,10 @@ describe('bootstrap', () => {
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule, RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpEnabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'enabled'})
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpEnabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'enabled'})
|
||||
],
|
||||
declarations: [RootCmp, TestCmpEnabled],
|
||||
bootstrap: [RootCmp],
|
||||
@ -81,7 +84,7 @@ describe('bootstrap', () => {
|
||||
|
||||
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
|
||||
const router = res.injector.get(Router);
|
||||
const data = router.routerState.snapshot.root.firstChild !.data;
|
||||
const data = router.routerState.snapshot.root.firstChild!.data;
|
||||
expect(data['test']).toEqual('test-data');
|
||||
expect(log).toEqual([
|
||||
'TestModule', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart',
|
||||
@ -141,9 +144,10 @@ describe('bootstrap', () => {
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule, RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpDiabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'disabled'})
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpDiabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'disabled'})
|
||||
],
|
||||
declarations: [RootCmp, TestCmpDiabled],
|
||||
bootstrap: [RootCmp],
|
||||
@ -250,7 +254,7 @@ describe('bootstrap', () => {
|
||||
});
|
||||
|
||||
|
||||
it('should restore the scrolling position', async(done) => {
|
||||
it('should restore the scrolling position', async (done) => {
|
||||
@Component({
|
||||
selector: 'component-a',
|
||||
template: `
|
||||
|
@ -32,12 +32,12 @@ describe('config', () => {
|
||||
it('should throw for undefined route in children', () => {
|
||||
expect(() => {
|
||||
validateConfig([{
|
||||
path: 'a',
|
||||
children: [
|
||||
{path: 'b', component: ComponentB},
|
||||
,
|
||||
]
|
||||
}] as any);
|
||||
path: 'a',
|
||||
children: [
|
||||
{path: 'b', component: ComponentB},
|
||||
,
|
||||
]
|
||||
}] as any);
|
||||
}).toThrowError(/Invalid configuration of route 'a'/);
|
||||
});
|
||||
|
||||
@ -66,46 +66,58 @@ describe('config', () => {
|
||||
});
|
||||
|
||||
it('should properly report deeply nested path', () => {
|
||||
expect(() => validateConfig([{
|
||||
path: 'a',
|
||||
children: [{path: 'b', children: [{path: 'c', children: [{path: 'd'}]}]}]
|
||||
}]))
|
||||
expect(
|
||||
() => validateConfig([
|
||||
{path: 'a', children: [{path: 'b', children: [{path: 'c', children: [{path: 'd'}]}]}]}
|
||||
]))
|
||||
.toThrowError(
|
||||
`Invalid configuration of route 'a/b/c/d'. One of the following must be provided: component, redirectTo, children or loadChildren`);
|
||||
});
|
||||
|
||||
it('should throw when redirectTo and loadChildren are used together', () => {
|
||||
expect(() => { validateConfig([{path: 'a', redirectTo: 'b', loadChildren: 'value'}]); })
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', redirectTo: 'b', loadChildren: 'value'}]);
|
||||
})
|
||||
.toThrowError(
|
||||
`Invalid configuration of route 'a': redirectTo and loadChildren cannot be used together`);
|
||||
});
|
||||
|
||||
it('should throw when children and loadChildren are used together', () => {
|
||||
expect(() => { validateConfig([{path: 'a', children: [], loadChildren: 'value'}]); })
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', children: [], loadChildren: 'value'}]);
|
||||
})
|
||||
.toThrowError(
|
||||
`Invalid configuration of route 'a': children and loadChildren cannot be used together`);
|
||||
});
|
||||
|
||||
it('should throw when component and redirectTo are used together', () => {
|
||||
expect(() => { validateConfig([{path: 'a', component: ComponentA, redirectTo: 'b'}]); })
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', component: ComponentA, redirectTo: 'b'}]);
|
||||
})
|
||||
.toThrowError(
|
||||
`Invalid configuration of route 'a': redirectTo and component cannot be used together`);
|
||||
});
|
||||
|
||||
it('should throw when path and matcher are used together', () => {
|
||||
expect(() => { validateConfig([{path: 'a', matcher: <any>'someFunc', children: []}]); })
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', matcher: <any>'someFunc', children: []}]);
|
||||
})
|
||||
.toThrowError(
|
||||
`Invalid configuration of route 'a': path and matcher cannot be used together`);
|
||||
});
|
||||
|
||||
it('should throw when path and matcher are missing', () => {
|
||||
expect(() => { validateConfig([{component: null, redirectTo: 'b'}] as any); })
|
||||
expect(() => {
|
||||
validateConfig([{component: null, redirectTo: 'b'}] as any);
|
||||
})
|
||||
.toThrowError(
|
||||
`Invalid configuration of route '': routes must have either a path or a matcher specified`);
|
||||
});
|
||||
|
||||
it('should throw when none of component and children or direct are missing', () => {
|
||||
expect(() => { validateConfig([{path: 'a'}]); })
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a'}]);
|
||||
})
|
||||
.toThrowError(
|
||||
`Invalid configuration of route 'a'. One of the following must be provided: component, redirectTo, children or loadChildren`);
|
||||
});
|
||||
@ -124,13 +136,17 @@ describe('config', () => {
|
||||
});
|
||||
|
||||
it('should throw when pathMatch is invalid', () => {
|
||||
expect(() => { validateConfig([{path: 'a', pathMatch: 'invalid', component: ComponentB}]); })
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', pathMatch: 'invalid', component: ComponentB}]);
|
||||
})
|
||||
.toThrowError(
|
||||
/Invalid configuration of route 'a': pathMatch can only be set to 'prefix' or 'full'/);
|
||||
});
|
||||
|
||||
it('should throw when path/outlet combination is invalid', () => {
|
||||
expect(() => { validateConfig([{path: 'a', outlet: 'aux'}]); })
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', outlet: 'aux'}]);
|
||||
})
|
||||
.toThrowError(
|
||||
/Invalid configuration of route 'a': a componentless route without children or loadChildren cannot have a named outlet set/);
|
||||
expect(() => validateConfig([{path: 'a', outlet: '', children: []}])).not.toThrow();
|
||||
@ -139,7 +155,9 @@ describe('config', () => {
|
||||
});
|
||||
|
||||
it('should not throw when path/outlet combination is valid', () => {
|
||||
expect(() => { validateConfig([{path: 'a', outlet: 'aux', children: []}]); }).not.toThrow();
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', outlet: 'aux', children: []}]);
|
||||
}).not.toThrow();
|
||||
expect(() => {
|
||||
validateConfig([{path: 'a', outlet: 'aux', loadChildren: 'child'}]);
|
||||
}).not.toThrow();
|
||||
|
@ -10,7 +10,7 @@ import {Routes} from '../src/config';
|
||||
import {createRouterState} from '../src/create_router_state';
|
||||
import {recognize} from '../src/recognize';
|
||||
import {DefaultRouteReuseStrategy} from '../src/route_reuse_strategy';
|
||||
import {ActivatedRoute, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from '../src/router_state';
|
||||
import {ActivatedRoute, advanceActivatedRoute, createEmptyState, RouterState, RouterStateSnapshot} from '../src/router_state';
|
||||
import {PRIMARY_OUTLET} from '../src/shared';
|
||||
import {DefaultUrlSerializer, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
||||
import {TreeNode} from '../src/utils/tree';
|
||||
@ -18,18 +18,19 @@ import {TreeNode} from '../src/utils/tree';
|
||||
describe('create router state', () => {
|
||||
const reuseStrategy = new DefaultRouteReuseStrategy();
|
||||
|
||||
const emptyState = () => createEmptyState(
|
||||
new (UrlTree as any)(new UrlSegmentGroup([], {}), {}, null !), RootComponent);
|
||||
const emptyState = () =>
|
||||
createEmptyState(new (UrlTree as any)(new UrlSegmentGroup([], {}), {}, null!), RootComponent);
|
||||
|
||||
it('should create new state', () => {
|
||||
const state = createRouterState(
|
||||
reuseStrategy, createState(
|
||||
[
|
||||
{path: 'a', component: ComponentA},
|
||||
{path: 'b', component: ComponentB, outlet: 'left'},
|
||||
{path: 'c', component: ComponentC, outlet: 'right'}
|
||||
],
|
||||
'a(left:b//right:c)'),
|
||||
reuseStrategy,
|
||||
createState(
|
||||
[
|
||||
{path: 'a', component: ComponentA},
|
||||
{path: 'b', component: ComponentB, outlet: 'left'},
|
||||
{path: 'c', component: ComponentC, outlet: 'right'}
|
||||
],
|
||||
'a(left:b//right:c)'),
|
||||
emptyState());
|
||||
|
||||
checkActivatedRoute(state.root, RootComponent);
|
||||
@ -63,9 +64,8 @@ describe('create router state', () => {
|
||||
it('should handle componentless routes', () => {
|
||||
const config = [{
|
||||
path: 'a/:id',
|
||||
children: [
|
||||
{path: 'b', component: ComponentA}, {path: 'c', component: ComponentB, outlet: 'right'}
|
||||
]
|
||||
children:
|
||||
[{path: 'b', component: ComponentA}, {path: 'c', component: ComponentB, outlet: 'right'}]
|
||||
}];
|
||||
|
||||
|
||||
@ -76,8 +76,8 @@ describe('create router state', () => {
|
||||
createRouterState(reuseStrategy, createState(config, 'a/2;p=22/(b//right:c)'), prevState);
|
||||
|
||||
expect(prevState.root).toBe(state.root);
|
||||
const prevP = (prevState as any).firstChild(prevState.root) !;
|
||||
const currP = (state as any).firstChild(state.root) !;
|
||||
const prevP = (prevState as any).firstChild(prevState.root)!;
|
||||
const currP = (state as any).firstChild(state.root)!;
|
||||
expect(prevP).toBe(currP);
|
||||
|
||||
const currC = (state as any).children(currP);
|
||||
@ -121,7 +121,7 @@ function advanceNode(node: TreeNode<ActivatedRoute>): void {
|
||||
}
|
||||
|
||||
function createState(config: Routes, url: string): RouterStateSnapshot {
|
||||
let res: RouterStateSnapshot = undefined !;
|
||||
let res: RouterStateSnapshot = undefined!;
|
||||
recognize(RootComponent, config, tree(url), url).forEach(s => res = s);
|
||||
return res;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import {BehaviorSubject} from 'rxjs';
|
||||
|
||||
import {createUrlTree} from '../src/create_url_tree';
|
||||
import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute} from '../src/router_state';
|
||||
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
||||
import {Params, PRIMARY_OUTLET} from '../src/shared';
|
||||
import {DefaultUrlSerializer, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
||||
|
||||
describe('createUrlTree', () => {
|
||||
@ -247,10 +247,10 @@ function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragme
|
||||
[], <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1,
|
||||
<any>null);
|
||||
const a = new (ActivatedRoute as any)(
|
||||
new BehaviorSubject(null !), new BehaviorSubject(null !), new BehaviorSubject(null !),
|
||||
new BehaviorSubject(null !), new BehaviorSubject(null !), PRIMARY_OUTLET, 'someComponent', s);
|
||||
new BehaviorSubject(null!), new BehaviorSubject(null!), new BehaviorSubject(null!),
|
||||
new BehaviorSubject(null!), new BehaviorSubject(null!), PRIMARY_OUTLET, 'someComponent', s);
|
||||
advanceActivatedRoute(a);
|
||||
return createUrlTree(a, tree, commands, queryParams !, fragment !);
|
||||
return createUrlTree(a, tree, commands, queryParams!, fragment!);
|
||||
}
|
||||
|
||||
function create(
|
||||
@ -263,8 +263,8 @@ function create(
|
||||
[], <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment,
|
||||
startIndex, <any>null);
|
||||
const a = new (ActivatedRoute as any)(
|
||||
new BehaviorSubject(null !), new BehaviorSubject(null !), new BehaviorSubject(null !),
|
||||
new BehaviorSubject(null !), new BehaviorSubject(null !), PRIMARY_OUTLET, 'someComponent', s);
|
||||
new BehaviorSubject(null!), new BehaviorSubject(null!), new BehaviorSubject(null!),
|
||||
new BehaviorSubject(null!), new BehaviorSubject(null!), PRIMARY_OUTLET, 'someComponent', s);
|
||||
advanceActivatedRoute(a);
|
||||
return createUrlTree(a, tree, commands, queryParams !, fragment !);
|
||||
return createUrlTree(a, tree, commands, queryParams!, fragment!);
|
||||
}
|
||||
|
@ -10,13 +10,17 @@ import {Type} from '@angular/core';
|
||||
|
||||
import {Data, ResolveData, Route} from '../src/config';
|
||||
import {ActivatedRouteSnapshot} from '../src/router_state';
|
||||
import {PRIMARY_OUTLET, ParamMap, Params, convertToParamMap} from '../src/shared';
|
||||
import {UrlSegment, UrlSegmentGroup, UrlTree, equalSegments} from '../src/url_tree';
|
||||
import {convertToParamMap, ParamMap, Params, PRIMARY_OUTLET} from '../src/shared';
|
||||
import {equalSegments, UrlSegment, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
||||
|
||||
export class Logger {
|
||||
logs: string[] = [];
|
||||
add(thing: string) { this.logs.push(thing); }
|
||||
empty() { this.logs.length = 0; }
|
||||
add(thing: string) {
|
||||
this.logs.push(thing);
|
||||
}
|
||||
empty() {
|
||||
this.logs.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
export function provideTokenLogger(token: string, returnValue = true as boolean | UrlTree) {
|
||||
@ -33,8 +37,7 @@ export declare type ARSArgs = {
|
||||
queryParams?: Params,
|
||||
fragment?: string,
|
||||
data?: Data,
|
||||
outlet?: string,
|
||||
component: Type<any>| string | null,
|
||||
outlet?: string, component: Type<any>| string | null,
|
||||
routeConfig?: Route | null,
|
||||
urlSegment?: UrlSegmentGroup,
|
||||
lastPathIndex?: number,
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
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 {TestScheduler} from 'rxjs/testing';
|
||||
|
||||
@ -23,13 +23,18 @@ describe('prioritizedGuardValue operator', () => {
|
||||
let router: Router;
|
||||
const TF = {T: true, F: false};
|
||||
|
||||
beforeEach(() => { TestBed.configureTestingModule({imports: [RouterTestingModule]}); });
|
||||
beforeEach(() => { testScheduler = new TestScheduler(assertDeepEquals); });
|
||||
beforeEach(() => { router = TestBed.inject(Router); });
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({imports: [RouterTestingModule]});
|
||||
});
|
||||
beforeEach(() => {
|
||||
testScheduler = new TestScheduler(assertDeepEquals);
|
||||
});
|
||||
beforeEach(() => {
|
||||
router = TestBed.inject(Router);
|
||||
});
|
||||
|
||||
it('should return true if all values are true', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const a = cold(' --(T|)', TF);
|
||||
const b = cold(' ----------(T|)', TF);
|
||||
const c = cold(' ------(T|)', TF);
|
||||
@ -38,13 +43,15 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' -------------T--';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, TF, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
TF,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return false if observables to the left of false have produced a value', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const a = cold(' --(T|)', TF);
|
||||
const b = cold(' ----------(T|)', TF);
|
||||
const c = cold(' ------(F|)', TF);
|
||||
@ -53,13 +60,15 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' -------------F--';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, TF, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
TF,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
it('should ignore results for unresolved sets of Observables', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const a = cold(' --(T|)', TF);
|
||||
const b = cold(' -------------(T|)', TF);
|
||||
const c = cold(' ------(F|)', TF);
|
||||
@ -71,13 +80,15 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' ------------T---';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, TF, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
TF,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return UrlTree if higher priority guards have resolved', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const urlTree = router.parseUrl('/');
|
||||
|
||||
const urlLookup = {U: urlTree};
|
||||
@ -91,13 +102,15 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' -------------U---';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, urlLookup, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
urlLookup,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return false even with UrlTree if UrlTree is lower priority', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const urlTree = router.parseUrl('/');
|
||||
|
||||
const urlLookup = {U: urlTree};
|
||||
@ -111,13 +124,15 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' -------------F---';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, TF, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
TF,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return UrlTree even after a false if the false is lower priority', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const urlTree = router.parseUrl('/');
|
||||
|
||||
const urlLookup = {U: urlTree};
|
||||
@ -131,13 +146,15 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' -------------U----';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, urlLookup, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
urlLookup,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the highest priority UrlTree', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const urlTreeU = router.parseUrl('/u');
|
||||
const urlTreeR = router.parseUrl('/r');
|
||||
const urlTreeL = router.parseUrl('/l');
|
||||
@ -153,13 +170,15 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' -------------U---';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, urlLookup, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
urlLookup,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
it('should propagate errors', () => {
|
||||
testScheduler.run(({hot, cold, expectObservable}) => {
|
||||
|
||||
const a = cold(' --(T|)', TF);
|
||||
const b = cold(' ------#', TF);
|
||||
const c = cold(' ----------(F|)', TF);
|
||||
@ -168,11 +187,12 @@ describe('prioritizedGuardValue operator', () => {
|
||||
const expected = ' ---------#';
|
||||
|
||||
expectObservable(source.pipe(prioritizedGuardValue()))
|
||||
.toBe(expected, TF, /* an error here maybe */);
|
||||
.toBe(
|
||||
expected,
|
||||
TF,
|
||||
/* an error here maybe */);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@ -9,21 +9,21 @@
|
||||
import {Routes} from '../src/config';
|
||||
import {recognize} from '../src/recognize';
|
||||
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../src/router_state';
|
||||
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
||||
import {Params, PRIMARY_OUTLET} from '../src/shared';
|
||||
import {DefaultUrlSerializer, UrlTree} from '../src/url_tree';
|
||||
|
||||
describe('recognize', () => {
|
||||
it('should work', () => {
|
||||
checkRecognize([{path: 'a', component: ComponentA}], 'a', (s: any) => {
|
||||
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute(s.firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
|
||||
it('should freeze params object', () => {
|
||||
checkRecognize([{path: 'a/:id', component: ComponentA}], 'a/10', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||
const child = (s as any).firstChild(s.root) !;
|
||||
const child = (s as any).firstChild(s.root)!;
|
||||
expect(Object.isFrozen(child.params)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -79,11 +79,11 @@ describe('recognize', () => {
|
||||
expect((s.root as any)._urlSegment).toBe(url.root);
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const compA = (s as any).firstChild(s.root) !;
|
||||
const compA = (s as any).firstChild(s.root)!;
|
||||
expect(compA._urlSegment).toBe((url.root as any).children[PRIMARY_OUTLET]);
|
||||
expect(compA._lastPathIndex).toBe(1);
|
||||
|
||||
const compC = (s as any).firstChild(<any>compA) !;
|
||||
const compC = (s as any).firstChild(<any>compA)!;
|
||||
expect(compC._urlSegment).toBe((url.root as any).children[PRIMARY_OUTLET]);
|
||||
expect(compC._lastPathIndex).toBe(2);
|
||||
});
|
||||
@ -101,11 +101,11 @@ describe('recognize', () => {
|
||||
expect(s.root._urlSegment).toBe(url.root);
|
||||
expect(s.root._lastPathIndex).toBe(-1);
|
||||
|
||||
const compA = (s as any).firstChild(s.root) !;
|
||||
const compA = (s as any).firstChild(s.root)!;
|
||||
expect(compA._urlSegment).toBe((url as any).root.children[PRIMARY_OUTLET]);
|
||||
expect(compA._lastPathIndex).toBe(0);
|
||||
|
||||
const compC = (s as any).firstChild(<any>compA) !;
|
||||
const compC = (s as any).firstChild(<any>compA)!;
|
||||
expect(compC._urlSegment).toBe((url as any).root.children[PRIMARY_OUTLET]);
|
||||
expect(compC._lastPathIndex).toBe(2);
|
||||
});
|
||||
@ -119,9 +119,9 @@ describe('recognize', () => {
|
||||
],
|
||||
'a/paramA', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
checkActivatedRoute(
|
||||
(s as any).firstChild(<any>(s as any).firstChild(s.root)) !, 'paramA', {id: 'paramA'},
|
||||
(s as any).firstChild(<any>(s as any).firstChild(s.root))!, 'paramA', {id: 'paramA'},
|
||||
ComponentB);
|
||||
});
|
||||
|
||||
@ -130,7 +130,7 @@ describe('recognize', () => {
|
||||
(s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||
checkActivatedRoute(
|
||||
(s as any).firstChild(s.root) !, 'a/paramA', {id: 'paramA'}, ComponentC);
|
||||
(s as any).firstChild(s.root)!, 'a/paramA', {id: 'paramA'}, ComponentC);
|
||||
});
|
||||
});
|
||||
|
||||
@ -154,8 +154,7 @@ describe('recognize', () => {
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
children: [
|
||||
{path: 'b', component: ComponentB},
|
||||
{path: 'c', component: ComponentC, outlet: 'left'}
|
||||
{path: 'b', component: ComponentB}, {path: 'c', component: ComponentC, outlet: 'left'}
|
||||
]
|
||||
},
|
||||
],
|
||||
@ -190,7 +189,7 @@ describe('recognize', () => {
|
||||
const c = (s as any).children(s.root);
|
||||
checkActivatedRoute(c[0], 'a', {a1: '11', a2: '22'}, ComponentA);
|
||||
checkActivatedRoute(
|
||||
(s as any).firstChild(<any>c[0]) !, 'b', {b1: '111', b2: '222'}, ComponentB);
|
||||
(s as any).firstChild(<any>c[0])!, 'b', {b1: '111', b2: '222'}, ComponentB);
|
||||
checkActivatedRoute(c[1], 'c', {c1: '1111', c2: '2222'}, ComponentC, 'left');
|
||||
});
|
||||
});
|
||||
@ -199,7 +198,7 @@ describe('recognize', () => {
|
||||
it('should set static data', () => {
|
||||
checkRecognize(
|
||||
[{path: 'a', data: {one: 1}, component: ComponentA}], 'a', (s: RouterStateSnapshot) => {
|
||||
const r: ActivatedRouteSnapshot = (s as any).firstChild(s.root) !;
|
||||
const r: ActivatedRouteSnapshot = (s as any).firstChild(s.root)!;
|
||||
expect(r.data).toEqual({one: 1});
|
||||
});
|
||||
});
|
||||
@ -213,7 +212,7 @@ describe('recognize', () => {
|
||||
}],
|
||||
'a/b', (s: RouterStateSnapshot) => {
|
||||
const r: ActivatedRouteSnapshot =
|
||||
(s as any).firstChild(<any>(s as any).firstChild(s.root)) !;
|
||||
(s as any).firstChild(<any>(s as any).firstChild(s.root))!;
|
||||
expect(r.data).toEqual({one: 1, two: 2});
|
||||
});
|
||||
});
|
||||
@ -227,7 +226,7 @@ describe('recognize', () => {
|
||||
children: [{path: 'b', data: {two: 2}, component: ComponentB}]
|
||||
}],
|
||||
'a/b', (s: any /* RouterStateSnapshot */) => {
|
||||
const r: ActivatedRouteSnapshot = s.firstChild(<any>s.firstChild(s.root)) !;
|
||||
const r: ActivatedRouteSnapshot = s.firstChild(<any>s.firstChild(s.root))!;
|
||||
expect(r.data).toEqual({two: 2});
|
||||
});
|
||||
});
|
||||
@ -241,7 +240,7 @@ describe('recognize', () => {
|
||||
children: [{path: 'b', data: {two: 2}, component: ComponentB}]
|
||||
}],
|
||||
'a/b', (s: any /* RouterStateSnapshot */) => {
|
||||
const r: ActivatedRouteSnapshot = s.firstChild(<any>s.firstChild(s.root)) !;
|
||||
const r: ActivatedRouteSnapshot = s.firstChild(<any>s.firstChild(s.root))!;
|
||||
expect(r.data).toEqual({one: 1, two: 2});
|
||||
}, 'always');
|
||||
});
|
||||
@ -249,7 +248,7 @@ describe('recognize', () => {
|
||||
it('should set resolved data', () => {
|
||||
checkRecognize(
|
||||
[{path: 'a', resolve: {one: 'some-token'}, component: ComponentA}], 'a', (s: any) => {
|
||||
const r: any = s.firstChild(s.root) !;
|
||||
const r: any = s.firstChild(s.root)!;
|
||||
expect(r._resolve).toEqual({one: 'some-token'});
|
||||
});
|
||||
});
|
||||
@ -259,7 +258,7 @@ describe('recognize', () => {
|
||||
describe('root', () => {
|
||||
it('should work', () => {
|
||||
checkRecognize([{path: '', component: ComponentA}], '', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, '', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, '', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
|
||||
@ -267,7 +266,7 @@ describe('recognize', () => {
|
||||
checkRecognize(
|
||||
[{path: '', pathMatch: 'full', component: ComponentA}], '',
|
||||
(s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, '', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, '', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
|
||||
@ -275,9 +274,9 @@ describe('recognize', () => {
|
||||
checkRecognize(
|
||||
[{path: '', component: ComponentA, children: [{path: '', component: ComponentB}]}], '',
|
||||
(s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, '', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, '', {}, ComponentA);
|
||||
checkActivatedRoute(
|
||||
(s as any).firstChild(<any>(s as any).firstChild(s.root)) !, '', {}, ComponentB);
|
||||
(s as any).firstChild(<any>(s as any).firstChild(s.root))!, '', {}, ComponentB);
|
||||
});
|
||||
});
|
||||
|
||||
@ -291,11 +290,11 @@ describe('recognize', () => {
|
||||
expect(s.root._urlSegment).toBe(url.root);
|
||||
expect(s.root._lastPathIndex).toBe(-1);
|
||||
|
||||
const c = s.firstChild(s.root) !;
|
||||
const c = s.firstChild(s.root)!;
|
||||
expect(c._urlSegment).toBe(url.root);
|
||||
expect(c._lastPathIndex).toBe(-1);
|
||||
|
||||
const c2 = s.firstChild(<any>s.firstChild(s.root)) !;
|
||||
const c2 = s.firstChild(<any>s.firstChild(s.root))!;
|
||||
expect(c2._urlSegment).toBe(url.root);
|
||||
expect(c2._lastPathIndex).toBe(-1);
|
||||
});
|
||||
@ -306,17 +305,15 @@ describe('recognize', () => {
|
||||
[{
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
children: [
|
||||
{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}
|
||||
]
|
||||
children:
|
||||
[{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}]
|
||||
}],
|
||||
'/a;p=1', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {p: '1'}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {p: '1'}, ComponentA);
|
||||
checkActivatedRoute(
|
||||
(s as any).firstChild((s as any).firstChild(s.root) !) !, '', {p: '1'},
|
||||
ComponentB);
|
||||
(s as any).firstChild((s as any).firstChild(s.root)!)!, '', {p: '1'}, ComponentB);
|
||||
checkActivatedRoute(
|
||||
(s as any).firstChild((s as any).firstChild((s as any).firstChild(s.root) !) !) !,
|
||||
(s as any).firstChild((s as any).firstChild((s as any).firstChild(s.root)!)!)!,
|
||||
'', {p: '1'}, ComponentC);
|
||||
});
|
||||
});
|
||||
@ -329,14 +326,13 @@ describe('recognize', () => {
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
children: [
|
||||
{path: 'b', component: ComponentB},
|
||||
{path: '', component: ComponentC, outlet: 'aux'}
|
||||
{path: 'b', component: ComponentB}, {path: '', component: ComponentC, outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/b', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
|
||||
const c = (s as any).children((s as any).firstChild(s.root) !);
|
||||
const c = (s as any).children((s as any).firstChild(s.root)!);
|
||||
checkActivatedRoute(c[0], 'b', {}, ComponentB);
|
||||
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
|
||||
});
|
||||
@ -365,13 +361,13 @@ describe('recognize', () => {
|
||||
|
||||
checkRecognize(config, 'parent/b', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'parent', {}, undefined !);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'parent', {}, undefined!);
|
||||
|
||||
const cc = (s as any).children((s as any).firstChild(s.root) !);
|
||||
const cc = (s as any).children((s as any).firstChild(s.root)!);
|
||||
checkActivatedRoute(cc[0], '', {}, ComponentA);
|
||||
checkActivatedRoute(cc[1], '', {}, ComponentD, 'secondary');
|
||||
|
||||
checkActivatedRoute((s as any).firstChild(cc[0]) !, 'b', {}, ComponentB);
|
||||
checkActivatedRoute((s as any).firstChild(cc[0])!, 'b', {}, ComponentB);
|
||||
});
|
||||
});
|
||||
|
||||
@ -386,9 +382,9 @@ describe('recognize', () => {
|
||||
]
|
||||
}],
|
||||
'a/b', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
|
||||
const c = (s as any).children((s as any).firstChild(s.root) !);
|
||||
const c = (s as any).children((s as any).firstChild(s.root)!);
|
||||
expect(c.length).toEqual(1);
|
||||
checkActivatedRoute(c[0], 'b', {}, ComponentB);
|
||||
});
|
||||
@ -401,8 +397,7 @@ describe('recognize', () => {
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
children: [
|
||||
{path: 'b', component: ComponentB},
|
||||
{path: '', component: ComponentC, outlet: 'aux'}
|
||||
{path: 'b', component: ComponentB}, {path: '', component: ComponentC, outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
url, 'a/b')
|
||||
@ -410,11 +405,11 @@ describe('recognize', () => {
|
||||
expect(s.root._urlSegment).toBe(url.root);
|
||||
expect(s.root._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = s.firstChild(s.root) !;
|
||||
const a = s.firstChild(s.root)!;
|
||||
expect(a._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(a._lastPathIndex).toBe(0);
|
||||
|
||||
const b = s.firstChild(a) !;
|
||||
const b = s.firstChild(a)!;
|
||||
expect(b._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(b._lastPathIndex).toBe(1);
|
||||
|
||||
@ -429,24 +424,23 @@ describe('recognize', () => {
|
||||
recognize(
|
||||
RootComponent, [{
|
||||
path: 'a',
|
||||
children: [
|
||||
{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}
|
||||
]
|
||||
children:
|
||||
[{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}]
|
||||
}],
|
||||
url, 'a')
|
||||
.forEach((s: any) => {
|
||||
expect(s.root._urlSegment).toBe(url.root);
|
||||
expect(s.root._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = s.firstChild(s.root) !;
|
||||
const a = s.firstChild(s.root)!;
|
||||
expect(a._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(a._lastPathIndex).toBe(0);
|
||||
|
||||
const b = s.firstChild(a) !;
|
||||
const b = s.firstChild(a)!;
|
||||
expect(b._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(b._lastPathIndex).toBe(0);
|
||||
|
||||
const c = s.firstChild(b) !;
|
||||
const c = s.firstChild(b)!;
|
||||
expect(c._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(c._lastPathIndex).toBe(0);
|
||||
});
|
||||
@ -473,19 +467,19 @@ describe('recognize', () => {
|
||||
expect(s.root._urlSegment).toBe(url.root);
|
||||
expect(s.root._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = s.firstChild(s.root) !;
|
||||
const a = s.firstChild(s.root)!;
|
||||
expect(a._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(a._lastPathIndex).toBe(0);
|
||||
|
||||
const b = s.firstChild(a) !;
|
||||
const b = s.firstChild(a)!;
|
||||
expect(b._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(b._lastPathIndex).toBe(1);
|
||||
|
||||
const c = s.firstChild(b) !;
|
||||
const c = s.firstChild(b)!;
|
||||
expect(c._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(c._lastPathIndex).toBe(1);
|
||||
|
||||
const d = s.firstChild(c) !;
|
||||
const d = s.firstChild(c)!;
|
||||
expect(d._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||
expect(d._lastPathIndex).toBe(1);
|
||||
});
|
||||
@ -496,24 +490,23 @@ describe('recognize', () => {
|
||||
recognize(
|
||||
RootComponent, [{
|
||||
path: '',
|
||||
children: [
|
||||
{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}
|
||||
]
|
||||
children:
|
||||
[{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}]
|
||||
}],
|
||||
url, '')
|
||||
.forEach((s: any) => {
|
||||
expect(s.root._urlSegment).toBe(url.root);
|
||||
expect(s.root._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = (s as any).firstChild(s.root) !;
|
||||
const a = (s as any).firstChild(s.root)!;
|
||||
expect(a._urlSegment).toBe(url.root);
|
||||
expect(a._lastPathIndex).toBe(-1);
|
||||
|
||||
const b = (s as any).firstChild(a) !;
|
||||
const b = (s as any).firstChild(a)!;
|
||||
expect(b._urlSegment).toBe(url.root);
|
||||
expect(b._lastPathIndex).toBe(-1);
|
||||
|
||||
const c = (s as any).firstChild(b) !;
|
||||
const c = (s as any).firstChild(b)!;
|
||||
expect(c._urlSegment).toBe(url.root);
|
||||
expect(c._lastPathIndex).toBe(-1);
|
||||
});
|
||||
@ -532,9 +525,9 @@ describe('recognize', () => {
|
||||
]
|
||||
}],
|
||||
'a', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
|
||||
const c = (s as any).children((s as any).firstChild(s.root) !);
|
||||
const c = (s as any).children((s as any).firstChild(s.root)!);
|
||||
checkActivatedRoute(c[0], '', {}, ComponentB);
|
||||
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
|
||||
});
|
||||
@ -551,9 +544,9 @@ describe('recognize', () => {
|
||||
]
|
||||
}],
|
||||
'a', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
|
||||
const c = (s as any).children((s as any).firstChild(s.root) !);
|
||||
const c = (s as any).children((s as any).firstChild(s.root)!);
|
||||
checkActivatedRoute(c[0], '', {}, ComponentB);
|
||||
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
|
||||
});
|
||||
@ -570,9 +563,9 @@ describe('recognize', () => {
|
||||
]
|
||||
}],
|
||||
'a/(aux:c)', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
|
||||
const c = (s as any).children((s as any).firstChild(s.root) !);
|
||||
const c = (s as any).children((s as any).firstChild(s.root)!);
|
||||
checkActivatedRoute(c[0], '', {}, ComponentB);
|
||||
checkActivatedRoute(c[1], 'c', {}, ComponentC, 'aux');
|
||||
});
|
||||
@ -612,13 +605,13 @@ describe('recognize', () => {
|
||||
]
|
||||
}],
|
||||
'a/(d//aux:e)', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a', {}, ComponentA);
|
||||
|
||||
const c = (s as any).children((s as any).firstChild(s.root) !);
|
||||
const c = (s as any).children((s as any).firstChild(s.root)!);
|
||||
checkActivatedRoute(c[0], '', {}, ComponentB);
|
||||
checkActivatedRoute((s as any).firstChild(c[0]) !, 'd', {}, ComponentD);
|
||||
checkActivatedRoute((s as any).firstChild(c[0])!, 'd', {}, ComponentD);
|
||||
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
|
||||
checkActivatedRoute((s as any).firstChild(c[1]) !, 'e', {}, ComponentE);
|
||||
checkActivatedRoute((s as any).firstChild(c[1])!, 'e', {}, ComponentE);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -628,7 +621,7 @@ describe('recognize', () => {
|
||||
it('should support simple wildcards', () => {
|
||||
checkRecognize(
|
||||
[{path: '**', component: ComponentA}], 'a/b/c/d;a1=11', (s: RouterStateSnapshot) => {
|
||||
checkActivatedRoute((s as any).firstChild(s.root) !, 'a/b/c/d', {a1: '11'}, ComponentA);
|
||||
checkActivatedRoute((s as any).firstChild(s.root)!, 'a/b/c/d', {a1: '11'}, ComponentA);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -639,13 +632,12 @@ describe('recognize', () => {
|
||||
[{
|
||||
path: 'p/:id',
|
||||
children: [
|
||||
{path: 'a', component: ComponentA},
|
||||
{path: 'b', component: ComponentB, outlet: 'aux'}
|
||||
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'p/11;pp=22/(a;pa=33//aux:b;pb=44)', (s: RouterStateSnapshot) => {
|
||||
const p = (s as any).firstChild(s.root) !;
|
||||
checkActivatedRoute(p, 'p/11', {id: '11', pp: '22'}, undefined !);
|
||||
const p = (s as any).firstChild(s.root)!;
|
||||
checkActivatedRoute(p, 'p/11', {id: '11', pp: '22'}, undefined!);
|
||||
|
||||
const c = (s as any).children(p);
|
||||
checkActivatedRoute(c[0], 'a', {id: '11', pp: '22', pa: '33'}, ComponentA);
|
||||
@ -659,24 +651,22 @@ describe('recognize', () => {
|
||||
path: 'p/:id',
|
||||
children: [{
|
||||
path: 'a/:name',
|
||||
children: [{
|
||||
path: 'b',
|
||||
component: ComponentB,
|
||||
children: [{path: 'c', component: ComponentC}]
|
||||
}]
|
||||
children: [
|
||||
{path: 'b', component: ComponentB, children: [{path: 'c', component: ComponentC}]}
|
||||
]
|
||||
}]
|
||||
}],
|
||||
'p/11/a/victor/b/c', (s: RouterStateSnapshot) => {
|
||||
const p = (s as any).firstChild(s.root) !;
|
||||
checkActivatedRoute(p, 'p/11', {id: '11'}, undefined !);
|
||||
const p = (s as any).firstChild(s.root)!;
|
||||
checkActivatedRoute(p, 'p/11', {id: '11'}, undefined!);
|
||||
|
||||
const a = (s as any).firstChild(p) !;
|
||||
checkActivatedRoute(a, 'a/victor', {id: '11', name: 'victor'}, undefined !);
|
||||
const a = (s as any).firstChild(p)!;
|
||||
checkActivatedRoute(a, 'a/victor', {id: '11', name: 'victor'}, undefined!);
|
||||
|
||||
const b = (s as any).firstChild(a) !;
|
||||
const b = (s as any).firstChild(a)!;
|
||||
checkActivatedRoute(b, 'b', {id: '11', name: 'victor'}, ComponentB);
|
||||
|
||||
const c = (s as any).firstChild(b) !;
|
||||
const c = (s as any).firstChild(b)!;
|
||||
checkActivatedRoute(c, 'c', {}, ComponentC);
|
||||
});
|
||||
});
|
||||
@ -687,15 +677,13 @@ describe('recognize', () => {
|
||||
path: 'p/:id',
|
||||
children: [{
|
||||
path: 'a/:name',
|
||||
children: [{
|
||||
path: 'b',
|
||||
component: ComponentB,
|
||||
children: [{path: 'c', component: ComponentC}]
|
||||
}]
|
||||
children: [
|
||||
{path: 'b', component: ComponentB, children: [{path: 'c', component: ComponentC}]}
|
||||
]
|
||||
}]
|
||||
}],
|
||||
'p/11/a/victor/b/c', (s: any /* RouterStateSnapshot */) => {
|
||||
const c = s.firstChild(s.firstChild(s.firstChild(s.firstChild(s.root) !) !) !) !;
|
||||
const c = s.firstChild(s.firstChild(s.firstChild(s.firstChild(s.root)!)!)!)!;
|
||||
checkActivatedRoute(c, 'c', {id: '11', name: 'victor'}, ComponentC);
|
||||
}, 'always');
|
||||
});
|
||||
@ -707,7 +695,7 @@ describe('recognize', () => {
|
||||
[{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]}],
|
||||
'/a', (s: RouterStateSnapshot) => {
|
||||
const a = (s as any).firstChild(s.root);
|
||||
checkActivatedRoute(a !, 'a', {}, ComponentA);
|
||||
checkActivatedRoute(a!, 'a', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
|
||||
@ -722,7 +710,7 @@ describe('recognize', () => {
|
||||
]
|
||||
}],
|
||||
'/a', (s: RouterStateSnapshot) => {
|
||||
const a = (s as any).firstChild(s.root) !;
|
||||
const a = (s as any).firstChild(s.root)!;
|
||||
checkActivatedRoute(a, 'a', {}, ComponentA);
|
||||
checkActivatedRoute((a as any).children[0], '', {}, ComponentC, 'aux');
|
||||
});
|
||||
@ -746,9 +734,9 @@ describe('recognize', () => {
|
||||
children: [{path: 'b', component: ComponentB}]
|
||||
}] as any,
|
||||
'/a/1;p=99/b', (s: RouterStateSnapshot) => {
|
||||
const a = (s as any).root.firstChild !;
|
||||
const a = (s as any).root.firstChild!;
|
||||
checkActivatedRoute(a, 'a/1', {id: '1', p: '99'}, ComponentA);
|
||||
checkActivatedRoute((a as any).firstChild !, 'b', {}, ComponentB);
|
||||
checkActivatedRoute((a as any).firstChild!, 'b', {}, ComponentB);
|
||||
});
|
||||
});
|
||||
|
||||
@ -756,7 +744,7 @@ describe('recognize', () => {
|
||||
const matcher = (s: any, g: any, r: any) => s.length === 0 ? ({consumed: s}) : null;
|
||||
|
||||
checkRecognize([{matcher, component: ComponentA}] as any, '', (s: RouterStateSnapshot) => {
|
||||
const a = (s as any).root.firstChild !;
|
||||
const a = (s as any).root.firstChild!;
|
||||
checkActivatedRoute(a, '', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
@ -767,7 +755,7 @@ describe('recognize', () => {
|
||||
checkRecognize(
|
||||
[{path: 'a', component: ComponentA, children: [{matcher, component: ComponentB}]}] as any,
|
||||
'a', (s: RouterStateSnapshot) => {
|
||||
const a = (s as any).root.firstChild !;
|
||||
const a = (s as any).root.firstChild!;
|
||||
checkActivatedRoute(a, 'a', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
@ -800,8 +788,9 @@ describe('recognize', () => {
|
||||
describe('fragment', () => {
|
||||
it('should support fragment', () => {
|
||||
const config = [{path: 'a', component: ComponentA}];
|
||||
checkRecognize(
|
||||
config, 'a#f1', (s: RouterStateSnapshot) => { expect(s.root.fragment).toEqual('f1'); });
|
||||
checkRecognize(config, 'a#f1', (s: RouterStateSnapshot) => {
|
||||
expect(s.root.fragment).toEqual('f1');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -825,9 +814,11 @@ describe('recognize', () => {
|
||||
|
||||
function checkRecognize(
|
||||
config: Routes, url: string, callback: any,
|
||||
paramsInheritanceStrategy?: 'emptyOnly' | 'always'): void {
|
||||
paramsInheritanceStrategy?: 'emptyOnly'|'always'): void {
|
||||
recognize(RootComponent, config, tree(url), url, paramsInheritanceStrategy)
|
||||
.subscribe(callback, e => { throw e; });
|
||||
.subscribe(callback, e => {
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
function checkActivatedRoute(
|
||||
|
@ -8,12 +8,11 @@
|
||||
|
||||
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 {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/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'})
|
||||
@ -73,16 +72,18 @@ describe('Integration', () => {
|
||||
})
|
||||
class ComponentWithRouterLink {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@ViewChild(TemplateRef, {static: true}) templateRef !: TemplateRef<any>;
|
||||
@ViewChild(TemplateRef, {static: true}) templateRef!: TemplateRef<any>;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@ViewChild('container', {read: ViewContainerRef, static: true})
|
||||
container !: ViewContainerRef;
|
||||
container!: ViewContainerRef;
|
||||
|
||||
addLink() {
|
||||
this.container.createEmbeddedView(this.templateRef, {$implicit: '/simple'});
|
||||
}
|
||||
|
||||
removeLink() { this.container.clear(); }
|
||||
removeLink() {
|
||||
this.container.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({template: 'simple'})
|
||||
@ -108,9 +109,7 @@ describe('Integration', () => {
|
||||
|
||||
expect(fixture.nativeElement.innerHTML).toContain('isActive: false');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function advance<T>(fixture: ComponentFixture<T>): void {
|
||||
|
@ -7,9 +7,9 @@
|
||||
*/
|
||||
|
||||
import {Location} from '@angular/common';
|
||||
import {TestBed, inject} from '@angular/core/testing';
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {of } from 'rxjs';
|
||||
import {of} from 'rxjs';
|
||||
|
||||
import {Routes} from '../src/config';
|
||||
import {ChildActivationStart} from '../src/events';
|
||||
@ -17,19 +17,20 @@ import {checkGuards as checkGuardsOperator} from '../src/operators/check_guards'
|
||||
import {resolveData as resolveDataOperator} from '../src/operators/resolve_data';
|
||||
import {NavigationTransition, Router} from '../src/router';
|
||||
import {ChildrenOutletContexts} from '../src/router_outlet_context';
|
||||
import {RouterStateSnapshot, createEmptyStateSnapshot} from '../src/router_state';
|
||||
import {createEmptyStateSnapshot, RouterStateSnapshot} from '../src/router_state';
|
||||
import {DefaultUrlSerializer, UrlTree} from '../src/url_tree';
|
||||
import {getAllRouteGuards} from '../src/utils/preactivation';
|
||||
import {TreeNode} from '../src/utils/tree';
|
||||
|
||||
import {Logger, createActivatedRouteSnapshot, provideTokenLogger} from './helpers';
|
||||
import {createActivatedRouteSnapshot, Logger, provideTokenLogger} from './helpers';
|
||||
|
||||
describe('Router', () => {
|
||||
|
||||
describe('resetConfig', () => {
|
||||
class TestComponent {}
|
||||
|
||||
beforeEach(() => { TestBed.configureTestingModule({imports: [RouterTestingModule]}); });
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({imports: [RouterTestingModule]});
|
||||
});
|
||||
|
||||
it('should copy config to avoid mutations of user-provided objects', () => {
|
||||
const r: Router = TestBed.inject(Router);
|
||||
@ -38,12 +39,12 @@ describe('Router', () => {
|
||||
component: TestComponent,
|
||||
children: [{path: 'b', component: TestComponent}, {path: 'c', component: TestComponent}]
|
||||
}];
|
||||
const children = configs[0].children !;
|
||||
const children = configs[0].children!;
|
||||
|
||||
r.resetConfig(configs);
|
||||
|
||||
const rConfigs = r.config;
|
||||
const rChildren = rConfigs[0].children !;
|
||||
const rChildren = rConfigs[0].children!;
|
||||
|
||||
// routes array and shallow copy
|
||||
expect(configs).not.toBe(rConfigs);
|
||||
@ -63,7 +64,9 @@ describe('Router', () => {
|
||||
describe('resetRootComponentType', () => {
|
||||
class NewRootComponent {}
|
||||
|
||||
beforeEach(() => { TestBed.configureTestingModule({imports: [RouterTestingModule]}); });
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({imports: [RouterTestingModule]});
|
||||
});
|
||||
|
||||
it('should not change root route when updating the root component', () => {
|
||||
const r: Router = TestBed.inject(Router);
|
||||
@ -76,7 +79,9 @@ describe('Router', () => {
|
||||
});
|
||||
|
||||
describe('setUpLocationChangeListener', () => {
|
||||
beforeEach(() => { TestBed.configureTestingModule({imports: [RouterTestingModule]}); });
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({imports: [RouterTestingModule]});
|
||||
});
|
||||
|
||||
it('should be idempotent', inject([Router, Location], (r: Router, location: Location) => {
|
||||
r.setUpLocationChangeListener();
|
||||
@ -118,7 +123,6 @@ describe('Router', () => {
|
||||
const CDA_GRANDCHILD_REDIRECT = 'canDeactivate_grandchild_redirect';
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule],
|
||||
providers: [
|
||||
@ -137,11 +141,10 @@ describe('Router', () => {
|
||||
CDA_GRANDCHILD_REDIRECT, serializer.parse('/canDeactivate_grandchild_redirect'))
|
||||
]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
beforeEach(inject([Logger], (_logger: Logger) => {
|
||||
empty = createEmptyStateSnapshot(serializer.parse('/'), null !);
|
||||
empty = createEmptyStateSnapshot(serializer.parse('/'), null!);
|
||||
logger = _logger;
|
||||
events = [];
|
||||
}));
|
||||
@ -164,9 +167,15 @@ describe('Router', () => {
|
||||
guards: getAllRouteGuards(futureState, empty, new ChildrenOutletContexts())
|
||||
} as NavigationTransition;
|
||||
|
||||
of (testTransition).pipe(checkGuardsOperator(TestBed, (evt) => {
|
||||
events.push(evt);
|
||||
})).subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
|
||||
of(testTransition)
|
||||
.pipe(checkGuardsOperator(
|
||||
TestBed,
|
||||
(evt) => {
|
||||
events.push(evt);
|
||||
}))
|
||||
.subscribe((x) => result = !!x.guardsResult, (e) => {
|
||||
throw e;
|
||||
});
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(events.length).toEqual(2);
|
||||
@ -203,9 +212,15 @@ describe('Router', () => {
|
||||
guards: getAllRouteGuards(futureState, empty, new ChildrenOutletContexts())
|
||||
} as NavigationTransition;
|
||||
|
||||
of (testTransition).pipe(checkGuardsOperator(TestBed, (evt) => {
|
||||
events.push(evt);
|
||||
})).subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
|
||||
of(testTransition)
|
||||
.pipe(checkGuardsOperator(
|
||||
TestBed,
|
||||
(evt) => {
|
||||
events.push(evt);
|
||||
}))
|
||||
.subscribe((x) => result = !!x.guardsResult, (e) => {
|
||||
throw e;
|
||||
});
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(events.length).toEqual(6);
|
||||
@ -240,9 +255,15 @@ describe('Router', () => {
|
||||
guards: getAllRouteGuards(futureState, currentState, new ChildrenOutletContexts())
|
||||
} as NavigationTransition;
|
||||
|
||||
of (testTransition).pipe(checkGuardsOperator(TestBed, (evt) => {
|
||||
events.push(evt);
|
||||
})).subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
|
||||
of(testTransition)
|
||||
.pipe(checkGuardsOperator(
|
||||
TestBed,
|
||||
(evt) => {
|
||||
events.push(evt);
|
||||
}))
|
||||
.subscribe((x) => result = !!x.guardsResult, (e) => {
|
||||
throw e;
|
||||
});
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(events.length).toEqual(2);
|
||||
@ -290,9 +311,15 @@ describe('Router', () => {
|
||||
guards: getAllRouteGuards(futureState, currentState, new ChildrenOutletContexts())
|
||||
} as NavigationTransition;
|
||||
|
||||
of (testTransition).pipe(checkGuardsOperator(TestBed, (evt) => {
|
||||
events.push(evt);
|
||||
})).subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
|
||||
of(testTransition)
|
||||
.pipe(checkGuardsOperator(
|
||||
TestBed,
|
||||
(evt) => {
|
||||
events.push(evt);
|
||||
}))
|
||||
.subscribe((x) => result = !!x.guardsResult, (e) => {
|
||||
throw e;
|
||||
});
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(events.length).toEqual(4);
|
||||
@ -536,9 +563,9 @@ describe('Router', () => {
|
||||
{component: 'grandchild', routeConfig: {canActivate: [CA_GRANDCHILD]}});
|
||||
|
||||
const futureState = new (RouterStateSnapshot as any)(
|
||||
'url', new TreeNode(
|
||||
empty.root,
|
||||
[new TreeNode(childSnapshot, [new TreeNode(grandchildSnapshot, [])])]));
|
||||
'url', new TreeNode(empty.root, [
|
||||
new TreeNode(childSnapshot, [new TreeNode(grandchildSnapshot, [])])
|
||||
]));
|
||||
|
||||
checkGuards(futureState, empty, TestBed, (result) => {
|
||||
expect(serializer.serialize(result as UrlTree)).toBe('/' + CAC_CHILD_REDIRECT);
|
||||
@ -561,9 +588,9 @@ describe('Router', () => {
|
||||
{component: 'grandchild', routeConfig: {canActivate: [CA_GRANDCHILD_REDIRECT]}});
|
||||
|
||||
const futureState = new (RouterStateSnapshot as any)(
|
||||
'url', new TreeNode(
|
||||
empty.root,
|
||||
[new TreeNode(childSnapshot, [new TreeNode(grandchildSnapshot, [])])]));
|
||||
'url', new TreeNode(empty.root, [
|
||||
new TreeNode(childSnapshot, [new TreeNode(grandchildSnapshot, [])])
|
||||
]));
|
||||
|
||||
checkGuards(futureState, empty, TestBed, (result) => {
|
||||
expect(serializer.serialize(result as UrlTree)).toBe('/' + CA_GRANDCHILD_REDIRECT);
|
||||
@ -592,21 +619,19 @@ describe('Router', () => {
|
||||
const currentState = new (RouterStateSnapshot as any)(
|
||||
'prev', new TreeNode(empty.root, [new TreeNode(prevSnapshot, [])]));
|
||||
const futureState = new (RouterStateSnapshot as any)(
|
||||
'url', new TreeNode(
|
||||
empty.root,
|
||||
[new TreeNode(childSnapshot, [new TreeNode(grandchildSnapshot, [])])]));
|
||||
'url', new TreeNode(empty.root, [
|
||||
new TreeNode(childSnapshot, [new TreeNode(grandchildSnapshot, [])])
|
||||
]));
|
||||
|
||||
checkGuards(futureState, currentState, TestBed, (result) => {
|
||||
expect(serializer.serialize(result as UrlTree)).toBe('/' + CDA_CHILD_REDIRECT);
|
||||
expect(logger.logs).toEqual([CDA_CHILD_REDIRECT]);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolve', () => {
|
||||
|
||||
it('should resolve data', () => {
|
||||
/**
|
||||
* R --> R
|
||||
@ -619,7 +644,7 @@ describe('Router', () => {
|
||||
'url', new TreeNode(empty.root, [new TreeNode(n, [])]));
|
||||
|
||||
checkResolveData(s, empty, inj, () => {
|
||||
expect(s.root.firstChild !.data).toEqual({data: 'resolver_value'});
|
||||
expect(s.root.firstChild!.data).toEqual({data: 'resolver_value'});
|
||||
});
|
||||
});
|
||||
|
||||
@ -634,7 +659,7 @@ describe('Router', () => {
|
||||
const parentResolve = {data: 'resolver'};
|
||||
const childResolve = {};
|
||||
|
||||
const parent = createActivatedRouteSnapshot({component: null !, resolve: parentResolve});
|
||||
const parent = createActivatedRouteSnapshot({component: null!, resolve: parentResolve});
|
||||
const child = createActivatedRouteSnapshot({component: 'b', resolve: childResolve});
|
||||
|
||||
const s = new (RouterStateSnapshot as any)(
|
||||
@ -643,7 +668,7 @@ describe('Router', () => {
|
||||
const inj = {get: (token: any) => () => Promise.resolve(`${token}_value`)};
|
||||
|
||||
checkResolveData(s, empty, inj, () => {
|
||||
expect(s.root.firstChild !.firstChild !.data).toEqual({data: 'resolver_value'});
|
||||
expect(s.root.firstChild!.firstChild!.data).toEqual({data: 'resolver_value'});
|
||||
});
|
||||
});
|
||||
|
||||
@ -668,8 +693,8 @@ describe('Router', () => {
|
||||
const s2 = new (RouterStateSnapshot as any)(
|
||||
'url', new TreeNode(empty.root, [new TreeNode(n21, [new TreeNode(n22, [])])]));
|
||||
checkResolveData(s2, s1, inj, () => {
|
||||
expect(s2.root.firstChild !.data).toEqual({data: 'resolver1_value'});
|
||||
expect(s2.root.firstChild !.firstChild !.data).toEqual({data: 'resolver2_value'});
|
||||
expect(s2.root.firstChild!.data).toEqual({data: 'resolver1_value'});
|
||||
expect(s2.root.firstChild!.firstChild!.data).toEqual({data: 'resolver2_value'});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -680,27 +705,29 @@ function checkResolveData(
|
||||
future: RouterStateSnapshot, curr: RouterStateSnapshot, injector: any, check: any): void {
|
||||
// Since we only test the guards and their resolve data function, we don't need to provide
|
||||
// a full navigation transition object with all properties set.
|
||||
of ({
|
||||
guards: getAllRouteGuards(future, curr, new ChildrenOutletContexts())
|
||||
} as NavigationTransition)
|
||||
of({guards: getAllRouteGuards(future, curr, new ChildrenOutletContexts())} as
|
||||
NavigationTransition)
|
||||
.pipe(resolveDataOperator('emptyOnly', injector))
|
||||
.subscribe(check, (e) => { throw e; });
|
||||
.subscribe(check, (e) => {
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
function checkGuards(
|
||||
future: RouterStateSnapshot, curr: RouterStateSnapshot, injector: any,
|
||||
check: (result: boolean | UrlTree) => void): void {
|
||||
check: (result: boolean|UrlTree) => void): void {
|
||||
// Since we only test the guards, we don't need to provide a full navigation
|
||||
// transition object with all properties set.
|
||||
of ({
|
||||
guards: getAllRouteGuards(future, curr, new ChildrenOutletContexts())
|
||||
} as NavigationTransition)
|
||||
of({guards: getAllRouteGuards(future, curr, new ChildrenOutletContexts())} as
|
||||
NavigationTransition)
|
||||
.pipe(checkGuardsOperator(injector))
|
||||
.subscribe({
|
||||
next(t) {
|
||||
if (t.guardsResult === null) throw new Error('Guard result expected');
|
||||
return check(t.guardsResult);
|
||||
},
|
||||
error(e) { throw e; }
|
||||
error(e) {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {Compiler, Component, NgModule, NgModuleFactoryLoader, NgModuleRef} from '@angular/core';
|
||||
import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
|
||||
import {fakeAsync, inject, TestBed, tick} from '@angular/core/testing';
|
||||
import {PreloadAllModules, PreloadingStrategy, RouterPreloader} from '@angular/router';
|
||||
|
||||
import {Route, RouteConfigLoadEnd, RouteConfigLoadStart, Router, RouterModule} from '../index';
|
||||
@ -67,8 +67,7 @@ describe('RouterPreloader', () => {
|
||||
const events: Array<RouteConfigLoadStart|RouteConfigLoadEnd> = [];
|
||||
@NgModule({
|
||||
declarations: [LazyLoadedCmp],
|
||||
imports:
|
||||
[RouterModule.forChild([{path: 'LoadedModule2', component: LazyLoadedCmp}])]
|
||||
imports: [RouterModule.forChild([{path: 'LoadedModule2', component: LazyLoadedCmp}])]
|
||||
})
|
||||
class LoadedModule2 {
|
||||
}
|
||||
@ -98,13 +97,13 @@ describe('RouterPreloader', () => {
|
||||
const c = router.config;
|
||||
expect(c[0].loadChildren).toEqual('expected');
|
||||
|
||||
const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !;
|
||||
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 !;
|
||||
(loadedConfig.routes[0] as any)._loadedConfig!;
|
||||
const module2: any = loadedConfig2.module;
|
||||
expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2');
|
||||
expect(module2._parent).toBe(module);
|
||||
@ -126,57 +125,58 @@ describe('RouterPreloader', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should work', fakeAsync(inject(
|
||||
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler],
|
||||
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader,
|
||||
router: Router, testModule: NgModuleRef<any>, compiler: Compiler) => {
|
||||
@NgModule()
|
||||
class LoadedModule2 {
|
||||
}
|
||||
it('should work',
|
||||
fakeAsync(inject(
|
||||
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler],
|
||||
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router,
|
||||
testModule: NgModuleRef<any>, compiler: Compiler) => {
|
||||
@NgModule()
|
||||
class LoadedModule2 {
|
||||
}
|
||||
|
||||
const module2 = compiler.compileModuleSync(LoadedModule2).create(null);
|
||||
const module2 = compiler.compileModuleSync(LoadedModule2).create(null);
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild([
|
||||
<Route>{
|
||||
path: 'LoadedModule2',
|
||||
loadChildren: 'no',
|
||||
_loadedConfig: {
|
||||
routes: [{path: 'LoadedModule3', loadChildren: 'expected3'}],
|
||||
module: module2,
|
||||
}
|
||||
},
|
||||
])]
|
||||
})
|
||||
class LoadedModule1 {
|
||||
}
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild([
|
||||
<Route>{
|
||||
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', () => {
|
||||
@ -237,11 +237,11 @@ describe('RouterPreloader', () => {
|
||||
|
||||
tick();
|
||||
|
||||
const c = router.config as{_loadedConfig: LoadedRouterConfig}[];
|
||||
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);
|
||||
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);
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
@ -128,7 +128,9 @@ describe('RouterScroller', () => {
|
||||
}, 1000);
|
||||
return r;
|
||||
}))
|
||||
.subscribe((e: Scroll) => { viewportScroller.scrollToPosition(e.position); });
|
||||
.subscribe((e: Scroll) => {
|
||||
viewportScroller.scrollToPosition(e.position);
|
||||
});
|
||||
|
||||
events.next(new NavigationStart(1, '/a'));
|
||||
events.next(new NavigationEnd(1, '/a', '/a'));
|
||||
@ -158,8 +160,8 @@ describe('RouterScroller', () => {
|
||||
|
||||
|
||||
function createRouterScroller({scrollPositionRestoration, anchorScrolling}: {
|
||||
scrollPositionRestoration: 'disabled' | 'enabled' | 'top',
|
||||
anchorScrolling: 'disabled' | 'enabled'
|
||||
scrollPositionRestoration: 'disabled'|'enabled'|'top',
|
||||
anchorScrolling: 'disabled'|'enabled'
|
||||
}) {
|
||||
const events = new Subject<RouterEvent>();
|
||||
const router = <any>{
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
|
||||
import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, equalParamsAndUrlSegments} from '../src/router_state';
|
||||
import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute, equalParamsAndUrlSegments, RouterState, RouterStateSnapshot} from '../src/router_state';
|
||||
import {Params} from '../src/shared';
|
||||
import {UrlSegment} from '../src/url_tree';
|
||||
import {TreeNode} from '../src/utils/tree';
|
||||
@ -30,7 +30,9 @@ describe('RouterState & Snapshot', () => {
|
||||
state = new (RouterStateSnapshot as any)('url', root);
|
||||
});
|
||||
|
||||
it('should return first child', () => { expect(state.root.firstChild).toBe(b); });
|
||||
it('should return first child', () => {
|
||||
expect(state.root.firstChild).toBe(b);
|
||||
});
|
||||
|
||||
it('should return children', () => {
|
||||
const cc = state.root.children;
|
||||
@ -39,17 +41,17 @@ describe('RouterState & Snapshot', () => {
|
||||
});
|
||||
|
||||
it('should return root', () => {
|
||||
const b = state.root.firstChild !;
|
||||
const b = state.root.firstChild!;
|
||||
expect(b.root).toBe(state.root);
|
||||
});
|
||||
|
||||
it('should return parent', () => {
|
||||
const b = state.root.firstChild !;
|
||||
const b = state.root.firstChild!;
|
||||
expect(b.parent).toBe(state.root);
|
||||
});
|
||||
|
||||
it('should return path from root', () => {
|
||||
const b = state.root.firstChild !;
|
||||
const b = state.root.firstChild!;
|
||||
const p = b.pathFromRoot;
|
||||
expect(p[0]).toBe(state.root);
|
||||
expect(p[1]).toBe(b);
|
||||
@ -72,7 +74,9 @@ describe('RouterState & Snapshot', () => {
|
||||
state = new (RouterState as any)(root, <any>null);
|
||||
});
|
||||
|
||||
it('should return first child', () => { expect(state.root.firstChild).toBe(b); });
|
||||
it('should return first child', () => {
|
||||
expect(state.root.firstChild).toBe(b);
|
||||
});
|
||||
|
||||
it('should return children', () => {
|
||||
const cc = state.root.children;
|
||||
@ -81,17 +85,17 @@ describe('RouterState & Snapshot', () => {
|
||||
});
|
||||
|
||||
it('should return root', () => {
|
||||
const b = state.root.firstChild !;
|
||||
const b = state.root.firstChild!;
|
||||
expect(b.root).toBe(state.root);
|
||||
});
|
||||
|
||||
it('should return parent', () => {
|
||||
const b = state.root.firstChild !;
|
||||
const b = state.root.firstChild!;
|
||||
expect(b.parent).toBe(state.root);
|
||||
});
|
||||
|
||||
it('should return path from root', () => {
|
||||
const b = state.root.firstChild !;
|
||||
const b = state.root.firstChild!;
|
||||
const p = b.pathFromRoot;
|
||||
expect(p[0]).toBe(state.root);
|
||||
expect(p[1]).toBe(b);
|
||||
@ -102,7 +106,7 @@ describe('RouterState & Snapshot', () => {
|
||||
function createSnapshot(params: Params, url: UrlSegment[]): ActivatedRouteSnapshot {
|
||||
const snapshot = new (ActivatedRouteSnapshot as any)(
|
||||
url, params, <any>null, <any>null, <any>null, <any>null, <any>null, <any>null, <any>null,
|
||||
-1, null !);
|
||||
-1, null!);
|
||||
snapshot._routerState = new (RouterStateSnapshot as any)('', new TreeNode(snapshot, []));
|
||||
return snapshot;
|
||||
}
|
||||
@ -166,10 +170,11 @@ describe('RouterState & Snapshot', () => {
|
||||
});
|
||||
|
||||
describe('advanceActivatedRoute', () => {
|
||||
|
||||
let route: ActivatedRoute;
|
||||
|
||||
beforeEach(() => { route = createActivatedRoute('a'); });
|
||||
beforeEach(() => {
|
||||
route = createActivatedRoute('a');
|
||||
});
|
||||
|
||||
function createSnapshot(params: Params, url: UrlSegment[]): ActivatedRouteSnapshot {
|
||||
const queryParams = {};
|
||||
@ -177,7 +182,7 @@ describe('RouterState & Snapshot', () => {
|
||||
const data = {};
|
||||
const snapshot = new (ActivatedRouteSnapshot as any)(
|
||||
url, params, queryParams, fragment, data, <any>null, <any>null, <any>null, <any>null, -1,
|
||||
null !);
|
||||
null!);
|
||||
const state = new (RouterStateSnapshot as any)('', new TreeNode(snapshot, []));
|
||||
snapshot._routerState = state;
|
||||
return snapshot;
|
||||
@ -190,7 +195,9 @@ describe('RouterState & Snapshot', () => {
|
||||
(route as any)._futureSnapshot = secondPlace;
|
||||
|
||||
let hasSeenDataChange = false;
|
||||
route.data.forEach((data) => { hasSeenDataChange = true; });
|
||||
route.data.forEach((data) => {
|
||||
hasSeenDataChange = true;
|
||||
});
|
||||
advanceActivatedRoute(route);
|
||||
expect(hasSeenDataChange).toEqual(true);
|
||||
});
|
||||
@ -200,7 +207,7 @@ describe('RouterState & Snapshot', () => {
|
||||
function createActivatedRouteSnapshot(cmp: string) {
|
||||
return new (ActivatedRouteSnapshot as any)(
|
||||
<any>[], <any>null, <any>null, <any>null, <any>null, <any>null, <any>cmp, <any>null,
|
||||
<any>null, -1, null !);
|
||||
<any>null, -1, null!);
|
||||
}
|
||||
|
||||
function createActivatedRoute(cmp: string) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ParamMap, convertToParamMap} from '../src/shared';
|
||||
import {convertToParamMap, ParamMap} from '../src/shared';
|
||||
|
||||
describe('ParamsMap', () => {
|
||||
it('should returns whether a parameter is present', () => {
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {PRIMARY_OUTLET} from '../src/shared';
|
||||
import {DefaultUrlSerializer, UrlSegmentGroup, encodeUriFragment, encodeUriQuery, encodeUriSegment, serializePath} from '../src/url_tree';
|
||||
import {DefaultUrlSerializer, encodeUriFragment, encodeUriQuery, encodeUriSegment, serializePath, UrlSegmentGroup} from '../src/url_tree';
|
||||
|
||||
describe('url serializer', () => {
|
||||
const url = new DefaultUrlSerializer();
|
||||
@ -188,8 +188,8 @@ describe('url serializer', () => {
|
||||
|
||||
describe('encoding/decoding', () => {
|
||||
it('should encode/decode path segments and parameters', () => {
|
||||
const u =
|
||||
`/${encodeUriSegment("one two")};${encodeUriSegment("p 1")}=${encodeUriSegment("v 1")};${encodeUriSegment("p 2")}=${encodeUriSegment("v 2")}`;
|
||||
const u = `/${encodeUriSegment('one two')};${encodeUriSegment('p 1')}=${
|
||||
encodeUriSegment('v 1')};${encodeUriSegment('p 2')}=${encodeUriSegment('v 2')}`;
|
||||
const tree = url.parse(u);
|
||||
|
||||
expect(tree.root.children[PRIMARY_OUTLET].segments[0].path).toEqual('one two');
|
||||
@ -199,8 +199,8 @@ describe('url serializer', () => {
|
||||
});
|
||||
|
||||
it('should encode/decode "slash" in path segments and parameters', () => {
|
||||
const u =
|
||||
`/${encodeUriSegment("one/two")};${encodeUriSegment("p/1")}=${encodeUriSegment("v/1")}/three`;
|
||||
const u = `/${encodeUriSegment('one/two')};${encodeUriSegment('p/1')}=${
|
||||
encodeUriSegment('v/1')}/three`;
|
||||
const tree = url.parse(u);
|
||||
const segment = tree.root.children[PRIMARY_OUTLET].segments[0];
|
||||
expect(segment.path).toEqual('one/two');
|
||||
@ -211,8 +211,8 @@ describe('url serializer', () => {
|
||||
});
|
||||
|
||||
it('should encode/decode query params', () => {
|
||||
const u =
|
||||
`/one?${encodeUriQuery("p 1")}=${encodeUriQuery("v 1")}&${encodeUriQuery("p 2")}=${encodeUriQuery("v 2")}`;
|
||||
const u = `/one?${encodeUriQuery('p 1')}=${encodeUriQuery('v 1')}&${encodeUriQuery('p 2')}=${
|
||||
encodeUriQuery('v 2')}`;
|
||||
const tree = url.parse(u);
|
||||
|
||||
expect(tree.queryParams).toEqual({'p 1': 'v 1', 'p 2': 'v 2'});
|
||||
@ -263,7 +263,6 @@ describe('url serializer', () => {
|
||||
});
|
||||
|
||||
describe('special character encoding/decoding', () => {
|
||||
|
||||
// Tests specific to https://github.com/angular/angular/issues/10280
|
||||
it('should parse encoded parens in matrix params', () => {
|
||||
const auxRoutesUrl = '/abc;foo=(other:val)';
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {DefaultUrlSerializer, containsTree} from '../src/url_tree';
|
||||
import {containsTree, DefaultUrlSerializer} from '../src/url_tree';
|
||||
|
||||
describe('UrlTree', () => {
|
||||
const serializer = new DefaultUrlSerializer();
|
||||
@ -14,7 +14,9 @@ describe('UrlTree', () => {
|
||||
describe('DefaultUrlSerializer', () => {
|
||||
let serializer: DefaultUrlSerializer;
|
||||
|
||||
beforeEach(() => { serializer = new DefaultUrlSerializer(); });
|
||||
beforeEach(() => {
|
||||
serializer = new DefaultUrlSerializer();
|
||||
});
|
||||
|
||||
it('should parse query parameters', () => {
|
||||
const tree = serializer.parse('/path/to?k=v&k/(a;b)=c');
|
||||
|
@ -21,8 +21,8 @@ describe('tree', () => {
|
||||
});
|
||||
|
||||
it('should return the parent of a node (second child)', () => {
|
||||
const t = new Tree<any>(
|
||||
new TreeNode<number>(1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])])) as any;
|
||||
const t = new Tree<any>(new TreeNode<number>(
|
||||
1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])])) as any;
|
||||
expect(t.parent(1)).toEqual(null);
|
||||
expect(t.parent(3)).toEqual(1);
|
||||
});
|
||||
@ -40,8 +40,8 @@ describe('tree', () => {
|
||||
});
|
||||
|
||||
it('should return the siblings of a node', () => {
|
||||
const t = new Tree<any>(
|
||||
new TreeNode<number>(1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])])) as any;
|
||||
const t = new Tree<any>(new TreeNode<number>(
|
||||
1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])])) as any;
|
||||
expect(t.siblings(2)).toEqual([3]);
|
||||
expect(t.siblings(1)).toEqual([]);
|
||||
});
|
||||
|
Reference in New Issue
Block a user