2016-06-21 14:49:42 -04:00
|
|
|
import {RouterConfig} from '../src/config';
|
2016-06-01 16:29:28 -04:00
|
|
|
import {createRouterState} from '../src/create_router_state';
|
|
|
|
import {recognize} from '../src/recognize';
|
2016-06-21 14:49:42 -04:00
|
|
|
import {ActivatedRoute, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from '../src/router_state';
|
|
|
|
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
2016-06-21 14:56:40 -04:00
|
|
|
import {DefaultUrlSerializer, UrlSegment, UrlTree} from '../src/url_tree';
|
2016-06-21 14:49:42 -04:00
|
|
|
import {TreeNode} from '../src/utils/tree';
|
2016-06-01 16:29:28 -04:00
|
|
|
|
|
|
|
describe('create router state', () => {
|
2016-06-21 14:49:42 -04:00
|
|
|
const emptyState = () =>
|
|
|
|
createEmptyState(new UrlTree(new UrlSegment([], {}), {}, null), RootComponent);
|
2016-06-01 16:29:28 -04:00
|
|
|
|
|
|
|
it('should work create new state', () => {
|
2016-06-21 14:49:42 -04:00
|
|
|
const state = createRouterState(
|
|
|
|
createState(
|
|
|
|
[
|
|
|
|
{path: 'a', component: ComponentA},
|
|
|
|
{path: 'b', component: ComponentB, outlet: 'left'},
|
|
|
|
{path: 'c', component: ComponentC, outlet: 'right'}
|
|
|
|
],
|
|
|
|
'a(left:b//right:c)'),
|
|
|
|
emptyState());
|
2016-06-01 16:29:28 -04:00
|
|
|
|
|
|
|
checkActivatedRoute(state.root, RootComponent);
|
|
|
|
|
|
|
|
const c = state.children(state.root);
|
|
|
|
checkActivatedRoute(c[0], ComponentA);
|
|
|
|
checkActivatedRoute(c[1], ComponentB, 'left');
|
|
|
|
checkActivatedRoute(c[2], ComponentC, 'right');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should reuse existing nodes when it can', () => {
|
|
|
|
const config = [
|
2016-06-21 14:49:42 -04:00
|
|
|
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'left'},
|
2016-06-01 16:29:28 -04:00
|
|
|
{path: 'c', component: ComponentC, outlet: 'left'}
|
|
|
|
];
|
|
|
|
|
2016-06-21 14:49:42 -04:00
|
|
|
const prevState = createRouterState(createState(config, 'a(left:b)'), emptyState());
|
2016-06-02 17:44:57 -04:00
|
|
|
advanceState(prevState);
|
2016-06-21 14:49:42 -04:00
|
|
|
const state = createRouterState(createState(config, 'a(left:c)'), prevState);
|
2016-06-01 16:29:28 -04:00
|
|
|
|
|
|
|
expect(prevState.root).toBe(state.root);
|
|
|
|
const prevC = prevState.children(prevState.root);
|
|
|
|
const currC = state.children(state.root);
|
|
|
|
|
|
|
|
expect(prevC[0]).toBe(currC[0]);
|
|
|
|
expect(prevC[1]).not.toBe(currC[1]);
|
|
|
|
checkActivatedRoute(currC[1], ComponentC, 'left');
|
|
|
|
});
|
2016-06-19 17:44:20 -04:00
|
|
|
|
|
|
|
it('should handle componentless routes', () => {
|
2016-06-21 14:49:42 -04:00
|
|
|
const config = [{
|
|
|
|
path: 'a/:id',
|
|
|
|
children: [
|
|
|
|
{path: 'b', component: ComponentA}, {path: 'c', component: ComponentB, outlet: 'right'}
|
|
|
|
]
|
|
|
|
}];
|
2016-06-19 17:44:20 -04:00
|
|
|
|
|
|
|
|
2016-06-21 14:49:42 -04:00
|
|
|
const prevState = createRouterState(createState(config, 'a/1;p=11/(b//right:c)'), emptyState());
|
2016-06-19 17:44:20 -04:00
|
|
|
advanceState(prevState);
|
2016-06-21 14:49:42 -04:00
|
|
|
const state = createRouterState(createState(config, 'a/2;p=22/(b//right:c)'), prevState);
|
2016-06-19 17:44:20 -04:00
|
|
|
|
|
|
|
expect(prevState.root).toBe(state.root);
|
|
|
|
const prevP = prevState.firstChild(prevState.root);
|
|
|
|
const currP = state.firstChild(state.root);
|
|
|
|
expect(prevP).toBe(currP);
|
|
|
|
|
|
|
|
const prevC = prevState.children(prevP);
|
|
|
|
const currC = state.children(currP);
|
|
|
|
|
|
|
|
expect(currP._futureSnapshot.params).toEqual({id: '2', p: '22'});
|
|
|
|
checkActivatedRoute(currC[0], ComponentA);
|
|
|
|
checkActivatedRoute(currC[1], ComponentB, 'right');
|
|
|
|
});
|
2016-06-01 16:29:28 -04:00
|
|
|
});
|
|
|
|
|
2016-06-02 17:44:57 -04:00
|
|
|
function advanceState(state: RouterState): void {
|
|
|
|
advanceNode(state._root);
|
|
|
|
}
|
|
|
|
|
|
|
|
function advanceNode(node: TreeNode<ActivatedRoute>): void {
|
|
|
|
advanceActivatedRoute(node.value);
|
|
|
|
node.children.forEach(advanceNode);
|
|
|
|
}
|
|
|
|
|
2016-06-01 20:55:21 -04:00
|
|
|
function createState(config: RouterConfig, url: string): RouterStateSnapshot {
|
2016-06-15 19:45:19 -04:00
|
|
|
let res: RouterStateSnapshot;
|
2016-06-14 17:55:59 -04:00
|
|
|
recognize(RootComponent, config, tree(url), url).forEach(s => res = s);
|
2016-06-01 16:29:28 -04:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2016-06-21 14:49:42 -04:00
|
|
|
function checkActivatedRoute(
|
|
|
|
actual: ActivatedRoute, cmp: Function, outlet: string = PRIMARY_OUTLET): void {
|
2016-06-01 16:29:28 -04:00
|
|
|
if (actual === null) {
|
|
|
|
expect(actual).toBeDefined();
|
|
|
|
} else {
|
|
|
|
expect(actual.component).toBe(cmp);
|
|
|
|
expect(actual.outlet).toEqual(outlet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function tree(url: string): UrlTree {
|
|
|
|
return new DefaultUrlSerializer().parse(url);
|
|
|
|
}
|
|
|
|
|
|
|
|
class RootComponent {}
|
|
|
|
class ComponentA {}
|
|
|
|
class ComponentB {}
|
|
|
|
class ComponentC {}
|