feat(router): implement data and resolve

This commit is contained in:
vsavkin
2016-06-27 14:00:07 -07:00
parent e913d9954d
commit f2f1ec0117
11 changed files with 318 additions and 56 deletions

View File

@ -167,10 +167,11 @@ describe('createUrlTree', () => {
});
function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
const s =
new ActivatedRouteSnapshot([], <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1);
const s = new ActivatedRouteSnapshot(
[], <any>{}, <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1, <any>null);
const a = new ActivatedRoute(
new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s);
new BehaviorSubject(null), new BehaviorSubject(null), new BehaviorSubject(null),
PRIMARY_OUTLET, 'someComponent', s);
advanceActivatedRoute(a);
return createUrlTree(a, tree, commands, queryParams, fragment);
}
@ -182,9 +183,11 @@ function create(
expect(segment).toBeDefined();
}
const s = new ActivatedRouteSnapshot(
[], <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment, startIndex);
[], <any>{}, <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment, startIndex,
<any>null);
const a = new ActivatedRoute(
new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s);
new BehaviorSubject(null), new BehaviorSubject(null), new BehaviorSubject(null),
PRIMARY_OUTLET, 'someComponent', s);
advanceActivatedRoute(a);
return createUrlTree(a, tree, commands, queryParams, fragment);
}

View File

@ -154,6 +154,57 @@ describe('recognize', () => {
});
});
describe('data', () => {
it('should set static data', () => {
checkRecognize(
[{path: 'a', data: {one: 1}, component: ComponentA}], 'a', (s: RouterStateSnapshot) => {
const r: ActivatedRouteSnapshot = s.firstChild(s.root);
expect(r.data).toEqual({one: 1});
});
});
it('should merge componentless route\'s data', () => {
checkRecognize(
[{
path: 'a',
data: {one: 1},
children: [{path: 'b', data: {two: 2}, component: ComponentB}]
}],
'a/b', (s: RouterStateSnapshot) => {
const r: ActivatedRouteSnapshot = s.firstChild(<any>s.firstChild(s.root));
expect(r.data).toEqual({one: 1, two: 2});
});
});
it('should set resolved data', () => {
checkRecognize(
[{path: 'a', resolve: {one: 'some-token'}, component: ComponentA}], 'a',
(s: RouterStateSnapshot) => {
const r: ActivatedRouteSnapshot = s.firstChild(s.root);
expect(r._resolve.current).toEqual({one: 'some-token'});
});
});
it('should reuse componentless route\'s resolve', () => {
checkRecognize(
[{
path: 'a',
resolve: {one: 'one'},
children: [
{path: '', resolve: {two: 'two'}, component: ComponentB},
{path: '', resolve: {three: 'three'}, component: ComponentC, outlet: 'aux'}
]
}],
'a', (s: RouterStateSnapshot) => {
const a: ActivatedRouteSnapshot = s.firstChild(s.root);
const c: ActivatedRouteSnapshot[] = s.children(<any>a);
expect(c[0]._resolve.parent).toBe(a._resolve);
expect(c[1]._resolve.parent).toBe(a._resolve);
});
});
});
describe('empty path', () => {
describe('root', () => {
it('should work', () => {

View File

@ -11,7 +11,7 @@ import {expect} from '@angular/platform-browser/testing/matchers';
import {Observable} from 'rxjs/Observable';
import {of } from 'rxjs/observable/of';
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, DefaultUrlSerializer, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Params, ROUTER_DIRECTIVES, Router, RouterConfig, RouterOutletMap, RouterStateSnapshot, RoutesRecognized, UrlSerializer} from '../index';
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, DefaultUrlSerializer, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Params, ROUTER_DIRECTIVES, Resolve, Router, RouterConfig, RouterOutletMap, RouterStateSnapshot, RoutesRecognized, UrlSerializer} from '../index';
describe('Integration', () => {
@ -433,6 +433,68 @@ describe('Integration', () => {
.toHaveText('primary {simple} right {user victor}');
})));
describe('data', () => {
class ResolveSix implements Resolve<TeamCmp> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): number { return 6; }
}
beforeEachProviders(
() =>
[{provide: 'resolveTwo', useValue: (a: any, b: any) => 2},
{provide: 'resolveFour', useValue: (a: any, b: any) => 4},
{provide: 'resolveSix', useClass: ResolveSix}]);
it('should provide resolved data',
fakeAsync(inject(
[Router, TestComponentBuilder, Location],
(router: Router, tcb: TestComponentBuilder, location: Location) => {
const fixture = tcb.createFakeAsync(RootCmpWithTwoOutlets);
advance(fixture);
router.resetConfig([{
path: 'parent/:id',
data: {one: 1},
resolve: {two: 'resolveTwo'},
children: [
{path: '', data: {three: 3}, resolve: {four: 'resolveFour'}, component: RouteCmp},
{
path: '',
data: {five: 5},
resolve: {six: 'resolveSix'},
component: RouteCmp,
outlet: 'right'
}
]
}]);
router.navigateByUrl('/parent/1');
advance(fixture);
const primaryCmp = fixture.debugElement.children[1].componentInstance;
const rightCmp = fixture.debugElement.children[3].componentInstance;
expect(primaryCmp.route.snapshot.data).toEqual({one: 1, two: 2, three: 3, four: 4});
expect(rightCmp.route.snapshot.data).toEqual({one: 1, two: 2, five: 5, six: 6});
let primaryRecorded: any[] = [];
primaryCmp.route.data.forEach((rec: any) => primaryRecorded.push(rec));
let rightRecorded: any[] = [];
rightCmp.route.data.forEach((rec: any) => rightRecorded.push(rec));
router.navigateByUrl('/parent/2');
advance(fixture);
expect(primaryRecorded).toEqual([
{one: 1, three: 3, two: 2, four: 4}, {one: 1, three: 3, two: 2, four: 4}
]);
expect(rightRecorded).toEqual([
{one: 1, five: 5, two: 2, six: 6}, {one: 1, five: 5, two: 2, six: 6}
]);
})));
});
describe('router links', () => {
it('should support string router links',
fakeAsync(
@ -1120,6 +1182,11 @@ class QueryParamsAndFragmentCmp {
}
}
@Component({selector: 'route-cmp', template: `route`, directives: ROUTER_DIRECTIVES})
class RouteCmp {
constructor(public route: ActivatedRoute) {}
}
@Component({
selector: 'root-cmp',
template: `<router-outlet></router-outlet>`,