chore(router): clang-format
This commit is contained in:
parent
92d8bf9619
commit
d1f93072a8
|
@ -1,200 +1,212 @@
|
||||||
import {DefaultUrlSerializer} from '../src/url_serializer';
|
|
||||||
import {TreeNode} from '../src/utils/tree';
|
|
||||||
import {UrlTree, UrlSegment, equalPathsWithParams} from '../src/url_tree';
|
|
||||||
import {RouterConfig} from '../src/config';
|
|
||||||
import {applyRedirects} from '../src/apply_redirects';
|
import {applyRedirects} from '../src/apply_redirects';
|
||||||
|
import {RouterConfig} from '../src/config';
|
||||||
|
import {DefaultUrlSerializer} from '../src/url_serializer';
|
||||||
|
import {UrlSegment, UrlTree, equalPathsWithParams} from '../src/url_tree';
|
||||||
|
import {TreeNode} from '../src/utils/tree';
|
||||||
|
|
||||||
describe('applyRedirects', () => {
|
describe('applyRedirects', () => {
|
||||||
it("should return the same url tree when no redirects", () => {
|
it('should return the same url tree when no redirects', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]}
|
[{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]}],
|
||||||
], "/a/b", (t:UrlTree) => {
|
'/a/b', (t: UrlTree) => { compareTrees(t, tree('/a/b')); });
|
||||||
compareTrees(t, tree('/a/b'));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should add new segments when needed", () => {
|
it('should add new segments when needed', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a/b', redirectTo: 'a/b/c'},
|
[{path: 'a/b', redirectTo: 'a/b/c'}, {path: '**', component: ComponentC}], '/a/b',
|
||||||
{path: '**', component: ComponentC}
|
(t: UrlTree) => { compareTrees(t, tree('/a/b/c')); });
|
||||||
], "/a/b", (t:UrlTree) => {
|
|
||||||
compareTrees(t, tree('/a/b/c'));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle positional parameters", () => {
|
it('should handle positional parameters', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a/:aid/b/:bid', redirectTo: 'newa/:aid/newb/:bid'},
|
[
|
||||||
{path: '**', component: ComponentC}
|
{path: 'a/:aid/b/:bid', redirectTo: 'newa/:aid/newb/:bid'},
|
||||||
], "/a/1/b/2", (t:UrlTree) => {
|
{path: '**', component: ComponentC}
|
||||||
compareTrees(t, tree('/newa/1/newb/2'));
|
],
|
||||||
});
|
'/a/1/b/2', (t: UrlTree) => { compareTrees(t, tree('/newa/1/newb/2')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when cannot handle a positional parameter", () => {
|
it('should throw when cannot handle a positional parameter', () => {
|
||||||
applyRedirects(tree("/a/1"), [
|
applyRedirects(tree('/a/1'), [
|
||||||
{path: 'a/:id', redirectTo: 'a/:other'}
|
{path: 'a/:id', redirectTo: 'a/:other'}
|
||||||
]).subscribe(() => {}, (e) => {
|
]).subscribe(() => {}, (e) => {
|
||||||
expect(e.message).toEqual("Cannot redirect to 'a/:other'. Cannot find ':other'.");
|
expect(e.message).toEqual('Cannot redirect to \'a/:other\'. Cannot find \':other\'.');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should pass matrix parameters", () => {
|
it('should pass matrix parameters', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a/:id', redirectTo: 'd/a/:id/e'},
|
[{path: 'a/:id', redirectTo: 'd/a/:id/e'}, {path: '**', component: ComponentC}],
|
||||||
{path: '**', component: ComponentC}
|
'/a;p1=1/1;p2=2', (t: UrlTree) => { compareTrees(t, tree('/d/a;p1=1/1;p2=2/e')); });
|
||||||
], "/a;p1=1/1;p2=2", (t:UrlTree) => {
|
|
||||||
compareTrees(t, tree('/d/a;p1=1/1;p2=2/e'));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle preserve secondary routes", () => {
|
it('should handle preserve secondary routes', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a/:id', redirectTo: 'd/a/:id/e'},
|
[
|
||||||
{path: 'c/d', component: ComponentA, outlet: 'aux'},
|
{path: 'a/:id', redirectTo: 'd/a/:id/e'},
|
||||||
{path: '**', component: ComponentC}
|
{path: 'c/d', component: ComponentA, outlet: 'aux'}, {path: '**', component: ComponentC}
|
||||||
], "/a/1(aux:c/d)", (t:UrlTree) => {
|
],
|
||||||
compareTrees(t, tree('/d/a/1/e(aux:c/d)'));
|
'/a/1(aux:c/d)', (t: UrlTree) => { compareTrees(t, tree('/d/a/1/e(aux:c/d)')); });
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should redirect secondary routes", () => {
|
it('should redirect secondary routes', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a/:id', component: ComponentA},
|
[
|
||||||
{path: 'c/d', redirectTo: 'f/c/d/e', outlet: 'aux'},
|
{path: 'a/:id', component: ComponentA},
|
||||||
{path: '**', component: ComponentC, outlet: 'aux'}
|
{path: 'c/d', redirectTo: 'f/c/d/e', outlet: 'aux'},
|
||||||
], "/a/1(aux:c/d)", (t:UrlTree) => {
|
{path: '**', component: ComponentC, outlet: 'aux'}
|
||||||
compareTrees(t, tree('/a/1(aux:f/c/d/e)'));
|
],
|
||||||
});
|
'/a/1(aux:c/d)', (t: UrlTree) => { compareTrees(t, tree('/a/1(aux:f/c/d/e)')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should use the configuration of the route redirected to", () => {
|
it('should use the configuration of the route redirected to', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a', component: ComponentA, children: [
|
[
|
||||||
{path: 'b', component: ComponentB},
|
{
|
||||||
]},
|
path: 'a',
|
||||||
{path: 'c', redirectTo: 'a'}
|
component: ComponentA,
|
||||||
], "c/b", (t:UrlTree) => {
|
children: [
|
||||||
compareTrees(t, tree('a/b'));
|
{path: 'b', component: ComponentB},
|
||||||
});
|
]
|
||||||
|
},
|
||||||
|
{path: 'c', redirectTo: 'a'}
|
||||||
|
],
|
||||||
|
'c/b', (t: UrlTree) => { compareTrees(t, tree('a/b')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should redirect empty path", () => {
|
it('should redirect empty path', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a', component: ComponentA, children: [
|
[
|
||||||
{path: 'b', component: ComponentB},
|
{
|
||||||
]},
|
path: 'a',
|
||||||
{path: '', redirectTo: 'a'}
|
component: ComponentA,
|
||||||
], "b", (t:UrlTree) => {
|
children: [
|
||||||
compareTrees(t, tree('a/b'));
|
{path: 'b', component: ComponentB},
|
||||||
});
|
]
|
||||||
|
},
|
||||||
|
{path: '', redirectTo: 'a'}
|
||||||
|
],
|
||||||
|
'b', (t: UrlTree) => { compareTrees(t, tree('a/b')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should redirect empty path (global redirect)", () => {
|
it('should redirect empty path (global redirect)', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a', component: ComponentA, children: [
|
[
|
||||||
{path: 'b', component: ComponentB},
|
{
|
||||||
]},
|
path: 'a',
|
||||||
{path: '', redirectTo: '/a/b'}
|
component: ComponentA,
|
||||||
], "", (t:UrlTree) => {
|
children: [
|
||||||
compareTrees(t, tree('a/b'));
|
{path: 'b', component: ComponentB},
|
||||||
});
|
]
|
||||||
|
},
|
||||||
|
{path: '', redirectTo: '/a/b'}
|
||||||
|
],
|
||||||
|
'', (t: UrlTree) => { compareTrees(t, tree('a/b')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should support nested redirects", () => {
|
xit('should support nested redirects', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a', component: ComponentA, children: [
|
[
|
||||||
{path: 'b', component: ComponentB},
|
{
|
||||||
{path: '', redirectTo: 'b'}
|
path: 'a',
|
||||||
]},
|
component: ComponentA,
|
||||||
{path: '', redirectTo: 'a'}
|
children: [{path: 'b', component: ComponentB}, {path: '', redirectTo: 'b'}]
|
||||||
], "", (t:UrlTree) => {
|
},
|
||||||
compareTrees(t, tree('a/b'));
|
{path: '', redirectTo: 'a'}
|
||||||
});
|
],
|
||||||
|
'', (t: UrlTree) => { compareTrees(t, tree('a/b')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should support nested redirects (when redirected to an empty path)", () => {
|
xit('should support nested redirects (when redirected to an empty path)', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: '', component: ComponentA, children: [
|
[
|
||||||
{path: 'b', component: ComponentB},
|
{
|
||||||
{path: '', redirectTo: 'b'}
|
path: '',
|
||||||
]},
|
component: ComponentA,
|
||||||
{path: 'a', redirectTo: ''}
|
children: [{path: 'b', component: ComponentB}, {path: '', redirectTo: 'b'}]
|
||||||
], "a", (t:UrlTree) => {
|
},
|
||||||
compareTrees(t, tree('b'));
|
{path: 'a', redirectTo: ''}
|
||||||
});
|
],
|
||||||
|
'a', (t: UrlTree) => { compareTrees(t, tree('b')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should support redirects with both main and aux", () => {
|
xit('should support redirects with both main and aux', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a', children: [
|
[
|
||||||
{path: 'b', component: ComponentB},
|
{
|
||||||
{path: '', redirectTo: 'b'},
|
path: 'a',
|
||||||
|
children: [
|
||||||
|
{path: 'b', component: ComponentB}, {path: '', redirectTo: 'b'},
|
||||||
|
|
||||||
{path: 'c', component: ComponentC, outlet: 'aux'},
|
{path: 'c', component: ComponentC, outlet: 'aux'},
|
||||||
{path: '', redirectTo: 'c', outlet: 'aux'}
|
{path: '', redirectTo: 'c', outlet: 'aux'}
|
||||||
]},
|
]
|
||||||
{path: 'a', redirectTo: ''}
|
},
|
||||||
], "a", (t:UrlTree) => {
|
{path: 'a', redirectTo: ''}
|
||||||
compareTrees(t, tree('a/(b//aux:c)'));
|
],
|
||||||
});
|
'a', (t: UrlTree) => { compareTrees(t, tree('a/(b//aux:c)')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should redirect empty path route only when terminal", () => {
|
it('should redirect empty path route only when terminal', () => {
|
||||||
const config = [
|
const config = [
|
||||||
{path: 'a', component: ComponentA, children: [
|
{
|
||||||
{path: 'b', component: ComponentB},
|
path: 'a',
|
||||||
]},
|
component: ComponentA,
|
||||||
|
children: [
|
||||||
|
{path: 'b', component: ComponentB},
|
||||||
|
]
|
||||||
|
},
|
||||||
{path: '', redirectTo: 'a', terminal: true}
|
{path: '', redirectTo: 'a', terminal: true}
|
||||||
];
|
];
|
||||||
|
|
||||||
applyRedirects(tree("b"), config).subscribe((_) => {
|
applyRedirects(tree('b'), config)
|
||||||
throw "Should not be reached";
|
.subscribe(
|
||||||
}, e => {
|
(_) => { throw 'Should not be reached'; },
|
||||||
expect(e.message).toEqual("Cannot match any routes: 'b'");
|
e => { expect(e.message).toEqual('Cannot match any routes: \'b\''); });
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should redirect wild cards", () => {
|
it('should redirect wild cards', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: '404', component: ComponentA},
|
[
|
||||||
{path: '**', redirectTo: '/404'},
|
{path: '404', component: ComponentA},
|
||||||
], "/a/1(aux:c/d)", (t:UrlTree) => {
|
{path: '**', redirectTo: '/404'},
|
||||||
compareTrees(t, tree('/404'));
|
],
|
||||||
});
|
'/a/1(aux:c/d)', (t: UrlTree) => { compareTrees(t, tree('/404')); });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support global redirects", () => {
|
it('should support global redirects', () => {
|
||||||
checkRedirect([
|
checkRedirect(
|
||||||
{path: 'a', component: ComponentA, children: [
|
[
|
||||||
{path: 'b/:id', redirectTo: '/global/:id'}
|
{
|
||||||
]},
|
path: 'a',
|
||||||
{path: '**', component: ComponentC}
|
component: ComponentA,
|
||||||
], "/a/b/1", (t:UrlTree) => {
|
children: [{path: 'b/:id', redirectTo: '/global/:id'}]
|
||||||
compareTrees(t, tree('/global/1'));
|
},
|
||||||
});
|
{path: '**', component: ComponentC}
|
||||||
|
],
|
||||||
|
'/a/b/1', (t: UrlTree) => { compareTrees(t, tree('/global/1')); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkRedirect(config: RouterConfig, url: string, callback: any): void {
|
function checkRedirect(config: RouterConfig, url: string, callback: any): void {
|
||||||
applyRedirects(tree(url), config).subscribe(callback, e => {
|
applyRedirects(tree(url), config).subscribe(callback, e => { throw e; });
|
||||||
throw e;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function tree(url: string): UrlTree {
|
function tree(url: string): UrlTree {
|
||||||
return new DefaultUrlSerializer().parse(url);
|
return new DefaultUrlSerializer().parse(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function compareTrees(actual: UrlTree, expected: UrlTree): void{
|
function compareTrees(actual: UrlTree, expected: UrlTree): void {
|
||||||
const serializer = new DefaultUrlSerializer();
|
const serializer = new DefaultUrlSerializer();
|
||||||
const error = `"${serializer.serialize(actual)}" is not equal to "${serializer.serialize(expected)}"`;
|
const error =
|
||||||
|
`"${serializer.serialize(actual)}" is not equal to "${serializer.serialize(expected)}"`;
|
||||||
compareSegments(actual.root, expected.root, error);
|
compareSegments(actual.root, expected.root, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
function compareSegments(actual: UrlSegment, expected: UrlSegment, error: string): void{
|
function compareSegments(actual: UrlSegment, expected: UrlSegment, error: string): void {
|
||||||
expect(actual).toBeDefined(error);
|
expect(actual).toBeDefined(error);
|
||||||
expect(equalPathsWithParams(actual.pathsWithParams, expected.pathsWithParams)).toEqual(true, error);
|
expect(equalPathsWithParams(actual.pathsWithParams, expected.pathsWithParams))
|
||||||
|
.toEqual(true, error);
|
||||||
|
|
||||||
expect(Object.keys(actual.children).length).toEqual(Object.keys(expected.children).length, error);
|
expect(Object.keys(actual.children).length).toEqual(Object.keys(expected.children).length, error);
|
||||||
|
|
||||||
|
|
|
@ -1,63 +1,46 @@
|
||||||
import {validateConfig} from '../src/config';
|
import {validateConfig} from '../src/config';
|
||||||
|
|
||||||
describe('config', () => {
|
describe('config', () => {
|
||||||
describe("validateConfig", () => {
|
describe('validateConfig', () => {
|
||||||
it("should not throw when no errors", () => {
|
it('should not throw when no errors', () => {
|
||||||
validateConfig([
|
validateConfig([{path: '', redirectTo: 'b'}, {path: 'b', component: ComponentA}]);
|
||||||
{path: '', redirectTo: 'b'},
|
|
||||||
{path: 'b', component: ComponentA}
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when redirectTo and children are used together", () => {
|
it('should throw when redirectTo and children are used together', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
validateConfig([
|
validateConfig(
|
||||||
{
|
[{path: 'a', redirectTo: 'b', children: [{path: 'b', component: ComponentA}]}]);
|
||||||
path: 'a', redirectTo: 'b', children: [
|
})
|
||||||
{path: 'b', component: ComponentA}
|
.toThrowError(
|
||||||
]
|
`Invalid configuration of route 'a': redirectTo and children cannot be used together`);
|
||||||
}
|
|
||||||
]);
|
|
||||||
}).toThrowError(`Invalid configuration of route 'a': redirectTo and children cannot be used together`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when component and redirectTo are used together", () => {
|
it('should throw when component and redirectTo are used together', () => {
|
||||||
expect(() => {
|
expect(() => { validateConfig([{path: 'a', component: ComponentA, redirectTo: 'b'}]); })
|
||||||
validateConfig([
|
.toThrowError(
|
||||||
{path: 'a', component: ComponentA, redirectTo: 'b'}
|
`Invalid configuration of route 'a': redirectTo and component cannot be used together`);
|
||||||
]);
|
|
||||||
}).toThrowError(`Invalid configuration of route 'a': redirectTo and component cannot be used together`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when path is missing", () => {
|
it('should throw when path is missing', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
validateConfig([
|
validateConfig([{component: '', redirectTo: 'b'}]);
|
||||||
{component: '', redirectTo: 'b'}
|
|
||||||
]);
|
|
||||||
}).toThrowError(`Invalid route configuration: routes must have path specified`);
|
}).toThrowError(`Invalid route configuration: routes must have path specified`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when none of component and children or direct are missing", () => {
|
it('should throw when none of component and children or direct are missing', () => {
|
||||||
expect(() => {
|
expect(() => { validateConfig([{path: 'a'}]); })
|
||||||
validateConfig([
|
.toThrowError(
|
||||||
{path: 'a'}
|
`Invalid configuration of route 'a': component, redirectTo, children must be provided`);
|
||||||
]);
|
|
||||||
}).toThrowError(`Invalid configuration of route 'a': component, redirectTo, children must be provided`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when path starts with a slash", () => {
|
it('should throw when path starts with a slash', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
validateConfig([
|
validateConfig([<any>{path: '/a', componenta: '', redirectTo: 'b'}]);
|
||||||
<any>{path: '/a', componenta: '', redirectTo: 'b'}
|
|
||||||
]);
|
|
||||||
}).toThrowError(`Invalid route configuration of route '/a': path cannot start with a slash`);
|
}).toThrowError(`Invalid route configuration of route '/a': path cannot start with a slash`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
class ComponentA {
|
class ComponentA {}
|
||||||
}
|
class ComponentB {}
|
||||||
class ComponentB {
|
class ComponentC {}
|
||||||
}
|
|
||||||
class ComponentC {
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
import {DefaultUrlSerializer} from '../src/url_serializer';
|
import {RouterConfig} from '../src/config';
|
||||||
import {UrlTree, UrlSegment} from '../src/url_tree';
|
|
||||||
import {TreeNode} from '../src/utils/tree';
|
|
||||||
import {Params, PRIMARY_OUTLET} from '../src/shared';
|
|
||||||
import {ActivatedRoute, RouterState, RouterStateSnapshot, createEmptyState, advanceActivatedRoute} from '../src/router_state';
|
|
||||||
import {createRouterState} from '../src/create_router_state';
|
import {createRouterState} from '../src/create_router_state';
|
||||||
import {recognize} from '../src/recognize';
|
import {recognize} from '../src/recognize';
|
||||||
import {RouterConfig} from '../src/config';
|
import {ActivatedRoute, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from '../src/router_state';
|
||||||
|
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
||||||
|
import {DefaultUrlSerializer} from '../src/url_serializer';
|
||||||
|
import {UrlSegment, UrlTree} from '../src/url_tree';
|
||||||
|
import {TreeNode} from '../src/utils/tree';
|
||||||
|
|
||||||
describe('create router state', () => {
|
describe('create router state', () => {
|
||||||
const emptyState = () => createEmptyState(new UrlTree(new UrlSegment([], {}), {}, null), RootComponent);
|
const emptyState = () =>
|
||||||
|
createEmptyState(new UrlTree(new UrlSegment([], {}), {}, null), RootComponent);
|
||||||
|
|
||||||
it('should work create new state', () => {
|
it('should work create new state', () => {
|
||||||
const state = createRouterState(createState([
|
const state = createRouterState(
|
||||||
{path: 'a', component: ComponentA},
|
createState(
|
||||||
{path: 'b', component: ComponentB, outlet: 'left'},
|
[
|
||||||
{path: 'c', component: ComponentC, outlet: 'right'}
|
{path: 'a', component: ComponentA},
|
||||||
], "a(left:b//right:c)"), emptyState());
|
{path: 'b', component: ComponentB, outlet: 'left'},
|
||||||
|
{path: 'c', component: ComponentC, outlet: 'right'}
|
||||||
|
],
|
||||||
|
'a(left:b//right:c)'),
|
||||||
|
emptyState());
|
||||||
|
|
||||||
checkActivatedRoute(state.root, RootComponent);
|
checkActivatedRoute(state.root, RootComponent);
|
||||||
|
|
||||||
|
@ -27,14 +32,13 @@ describe('create router state', () => {
|
||||||
|
|
||||||
it('should reuse existing nodes when it can', () => {
|
it('should reuse existing nodes when it can', () => {
|
||||||
const config = [
|
const config = [
|
||||||
{path: 'a', component: ComponentA},
|
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'left'},
|
||||||
{path: 'b', component: ComponentB, outlet: 'left'},
|
|
||||||
{path: 'c', component: ComponentC, outlet: 'left'}
|
{path: 'c', component: ComponentC, outlet: 'left'}
|
||||||
];
|
];
|
||||||
|
|
||||||
const prevState = createRouterState(createState(config, "a(left:b)"), emptyState());
|
const prevState = createRouterState(createState(config, 'a(left:b)'), emptyState());
|
||||||
advanceState(prevState);
|
advanceState(prevState);
|
||||||
const state = createRouterState(createState(config, "a(left:c)"), prevState);
|
const state = createRouterState(createState(config, 'a(left:c)'), prevState);
|
||||||
|
|
||||||
expect(prevState.root).toBe(state.root);
|
expect(prevState.root).toBe(state.root);
|
||||||
const prevC = prevState.children(prevState.root);
|
const prevC = prevState.children(prevState.root);
|
||||||
|
@ -46,17 +50,17 @@ describe('create router state', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle componentless routes', () => {
|
it('should handle componentless routes', () => {
|
||||||
const config = [
|
const config = [{
|
||||||
{ path: 'a/:id', children: [
|
path: 'a/:id',
|
||||||
{ path: 'b', component: ComponentA },
|
children: [
|
||||||
{ path: 'c', component: ComponentB, outlet: 'right' }
|
{path: 'b', component: ComponentA}, {path: 'c', component: ComponentB, outlet: 'right'}
|
||||||
] }
|
]
|
||||||
];
|
}];
|
||||||
|
|
||||||
|
|
||||||
const prevState = createRouterState(createState(config, "a/1;p=11/(b//right:c)"), emptyState());
|
const prevState = createRouterState(createState(config, 'a/1;p=11/(b//right:c)'), emptyState());
|
||||||
advanceState(prevState);
|
advanceState(prevState);
|
||||||
const state = createRouterState(createState(config, "a/2;p=22/(b//right:c)"), prevState);
|
const state = createRouterState(createState(config, 'a/2;p=22/(b//right:c)'), prevState);
|
||||||
|
|
||||||
expect(prevState.root).toBe(state.root);
|
expect(prevState.root).toBe(state.root);
|
||||||
const prevP = prevState.firstChild(prevState.root);
|
const prevP = prevState.firstChild(prevState.root);
|
||||||
|
@ -87,7 +91,8 @@ function createState(config: RouterConfig, url: string): RouterStateSnapshot {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkActivatedRoute(actual: ActivatedRoute, cmp: Function, outlet: string = PRIMARY_OUTLET):void {
|
function checkActivatedRoute(
|
||||||
|
actual: ActivatedRoute, cmp: Function, outlet: string = PRIMARY_OUTLET): void {
|
||||||
if (actual === null) {
|
if (actual === null) {
|
||||||
expect(actual).toBeDefined();
|
expect(actual).toBeDefined();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,182 +1,191 @@
|
||||||
import {DefaultUrlSerializer} from '../src/url_serializer';
|
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
||||||
import {UrlTree, UrlPathWithParams, UrlSegment} from '../src/url_tree';
|
|
||||||
|
import {createUrlTree} from '../src/create_url_tree';
|
||||||
import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute} from '../src/router_state';
|
import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute} from '../src/router_state';
|
||||||
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
||||||
import {createUrlTree} from '../src/create_url_tree';
|
import {DefaultUrlSerializer} from '../src/url_serializer';
|
||||||
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
import {UrlPathWithParams, UrlSegment, UrlTree} from '../src/url_tree';
|
||||||
|
|
||||||
describe('createUrlTree', () => {
|
describe('createUrlTree', () => {
|
||||||
const serializer = new DefaultUrlSerializer();
|
const serializer = new DefaultUrlSerializer();
|
||||||
|
|
||||||
it("should navigate to the root", () => {
|
it('should navigate to the root', () => {
|
||||||
const p = serializer.parse("/");
|
const p = serializer.parse('/');
|
||||||
const t = createRoot(p, ["/"]);
|
const t = createRoot(p, ['/']);
|
||||||
expect(serializer.serialize(t)).toEqual("/");
|
expect(serializer.serialize(t)).toEqual('/');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support nested segments", () => {
|
it('should support nested segments', () => {
|
||||||
const p = serializer.parse("/a/b");
|
const p = serializer.parse('/a/b');
|
||||||
const t = createRoot(p, ["/one", 11, "two", 22]);
|
const t = createRoot(p, ['/one', 11, 'two', 22]);
|
||||||
expect(serializer.serialize(t)).toEqual("/one/11/two/22");
|
expect(serializer.serialize(t)).toEqual('/one/11/two/22');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("should stringify positional parameters", () => {
|
it('should stringify positional parameters', () => {
|
||||||
const p = serializer.parse("/a/b");
|
const p = serializer.parse('/a/b');
|
||||||
const t = createRoot(p, ["/one", 11]);
|
const t = createRoot(p, ['/one', 11]);
|
||||||
const params = t.root.children[PRIMARY_OUTLET].pathsWithParams;
|
const params = t.root.children[PRIMARY_OUTLET].pathsWithParams;
|
||||||
expect(params[0].path).toEqual("one");
|
expect(params[0].path).toEqual('one');
|
||||||
expect(params[1].path).toEqual("11");
|
expect(params[1].path).toEqual('11');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should preserve secondary segments", () => {
|
it('should preserve secondary segments', () => {
|
||||||
const p = serializer.parse("/a/11/b(right:c)");
|
const p = serializer.parse('/a/11/b(right:c)');
|
||||||
const t = createRoot(p, ["/a", 11, 'd']);
|
const t = createRoot(p, ['/a', 11, 'd']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/11/d(right:c)");
|
expect(serializer.serialize(t)).toEqual('/a/11/d(right:c)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support updating secondary segments", () => {
|
it('should support updating secondary segments', () => {
|
||||||
const p = serializer.parse("/a(right:b)");
|
const p = serializer.parse('/a(right:b)');
|
||||||
const t = createRoot(p, ["right:c", 11, 'd']);
|
const t = createRoot(p, ['right:c', 11, 'd']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a(right:c/11/d)");
|
expect(serializer.serialize(t)).toEqual('/a(right:c/11/d)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support updating secondary segments (nested case)", () => {
|
it('should support updating secondary segments (nested case)', () => {
|
||||||
const p = serializer.parse("/a/(b//right:c)");
|
const p = serializer.parse('/a/(b//right:c)');
|
||||||
const t = createRoot(p, ["a", "right:d", 11, 'e']);
|
const t = createRoot(p, ['a', 'right:d', 11, 'e']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/(b//right:d/11/e)");
|
expect(serializer.serialize(t)).toEqual('/a/(b//right:d/11/e)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update matrix parameters', () => {
|
it('should update matrix parameters', () => {
|
||||||
const p = serializer.parse("/a;pp=11");
|
const p = serializer.parse('/a;pp=11');
|
||||||
const t = createRoot(p, ["/a", {pp: 22, dd: 33}]);
|
const t = createRoot(p, ['/a', {pp: 22, dd: 33}]);
|
||||||
expect(serializer.serialize(t)).toEqual("/a;pp=22;dd=33");
|
expect(serializer.serialize(t)).toEqual('/a;pp=22;dd=33');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create matrix parameters', () => {
|
it('should create matrix parameters', () => {
|
||||||
const p = serializer.parse("/a");
|
const p = serializer.parse('/a');
|
||||||
const t = createRoot(p, ["/a", {pp: 22, dd: 33}]);
|
const t = createRoot(p, ['/a', {pp: 22, dd: 33}]);
|
||||||
expect(serializer.serialize(t)).toEqual("/a;pp=22;dd=33");
|
expect(serializer.serialize(t)).toEqual('/a;pp=22;dd=33');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create matrix parameters together with other segments', () => {
|
it('should create matrix parameters together with other segments', () => {
|
||||||
const p = serializer.parse("/a");
|
const p = serializer.parse('/a');
|
||||||
const t = createRoot(p, ["/a", "/b", {aa: 22, bb: 33}]);
|
const t = createRoot(p, ['/a', '/b', {aa: 22, bb: 33}]);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/b;aa=22;bb=33");
|
expect(serializer.serialize(t)).toEqual('/a/b;aa=22;bb=33');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("relative navigation", () => {
|
describe('relative navigation', () => {
|
||||||
it("should work", () => {
|
it('should work', () => {
|
||||||
const p = serializer.parse("/a/(c//left:cp)(left:ap)");
|
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ["c2"]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['c2']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/(c2//left:cp)(left:ap)");
|
expect(serializer.serialize(t)).toEqual('/a/(c2//left:cp)(left:ap)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should work when the first command starts with a ./", () => {
|
it('should work when the first command starts with a ./', () => {
|
||||||
const p = serializer.parse("/a/(c//left:cp)(left:ap)");
|
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ["./c2"]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['./c2']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/(c2//left:cp)(left:ap)");
|
expect(serializer.serialize(t)).toEqual('/a/(c2//left:cp)(left:ap)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should work when the first command is ./)", () => {
|
it('should work when the first command is ./)', () => {
|
||||||
const p = serializer.parse("/a/(c//left:cp)(left:ap)");
|
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ["./", "c2"]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['./', 'c2']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/(c2//left:cp)(left:ap)");
|
expect(serializer.serialize(t)).toEqual('/a/(c2//left:cp)(left:ap)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should work when given params", () => {
|
it('should work when given params', () => {
|
||||||
const p = serializer.parse("/a/(c//left:cp)(left:ap)");
|
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, [{'x': 99}]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, [{'x': 99}]);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/(c;x=99//left:cp)(left:ap)");
|
expect(serializer.serialize(t)).toEqual('/a/(c;x=99//left:cp)(left:ap)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should work when index > 0", () => {
|
it('should work when index > 0', () => {
|
||||||
const p = serializer.parse("/a/c");
|
const p = serializer.parse('/a/c');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ["c2"]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['c2']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/c/c2");
|
expect(serializer.serialize(t)).toEqual('/a/c/c2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support going to a parent (within a segment)", () => {
|
it('should support going to a parent (within a segment)', () => {
|
||||||
const p = serializer.parse("/a/c");
|
const p = serializer.parse('/a/c');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ["../c2"]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['../c2']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/c2");
|
expect(serializer.serialize(t)).toEqual('/a/c2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should work when given ../", () => {
|
it('should work when given ../', () => {
|
||||||
const p = serializer.parse("/a/c");
|
const p = serializer.parse('/a/c');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ["../", "c2"]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['../', 'c2']);
|
||||||
expect(serializer.serialize(t)).toEqual("/a/c2");
|
expect(serializer.serialize(t)).toEqual('/a/c2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support setting matrix params", () => {
|
it('should support setting matrix params', () => {
|
||||||
const p = serializer.parse("/a/(c//left:cp)(left:ap)");
|
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../', {x: 5}]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../', {x: 5}]);
|
||||||
expect(serializer.serialize(t)).toEqual("/a;x=5(left:ap)");
|
expect(serializer.serialize(t)).toEqual('/a;x=5(left:ap)');
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should support going to a parent (across segments)", () => {
|
xit('should support going to a parent (across segments)', () => {
|
||||||
const p = serializer.parse("/q/(a/(c//left:cp)//left:qp)(left:ap)");
|
const p = serializer.parse('/q/(a/(c//left:cp)//left:qp)(left:ap)');
|
||||||
|
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET].children[PRIMARY_OUTLET], 0, p, ['../../q2']);
|
const t =
|
||||||
expect(serializer.serialize(t)).toEqual("/q2(left:ap)");
|
create(p.root.children[PRIMARY_OUTLET].children[PRIMARY_OUTLET], 0, p, ['../../q2']);
|
||||||
|
expect(serializer.serialize(t)).toEqual('/q2(left:ap)');
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should navigate to the root", () => {
|
xit('should navigate to the root', () => {
|
||||||
const p = serializer.parse("/a/c");
|
const p = serializer.parse('/a/c');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../']);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../']);
|
||||||
expect(serializer.serialize(t)).toEqual("");
|
expect(serializer.serialize(t)).toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when too many ..", () => {
|
it('should throw when too many ..', () => {
|
||||||
const p = serializer.parse("/a/(c//left:cp)(left:ap)");
|
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||||
expect(() => create(p.root.children[PRIMARY_OUTLET], 0, p, ['../../'])).toThrowError("Invalid number of '../'");
|
expect(() => create(p.root.children[PRIMARY_OUTLET], 0, p, ['../../']))
|
||||||
|
.toThrowError('Invalid number of \'../\'');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set query params", () => {
|
it('should set query params', () => {
|
||||||
const p = serializer.parse("/");
|
const p = serializer.parse('/');
|
||||||
const t = createRoot(p, [], {a: 'hey'});
|
const t = createRoot(p, [], {a: 'hey'});
|
||||||
expect(t.queryParams).toEqual({a: 'hey'});
|
expect(t.queryParams).toEqual({a: 'hey'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should stringify query params", () => {
|
it('should stringify query params', () => {
|
||||||
const p = serializer.parse("/");
|
const p = serializer.parse('/');
|
||||||
const t = createRoot(p, [], <any>{a: 1});
|
const t = createRoot(p, [], <any>{a: 1});
|
||||||
expect(t.queryParams).toEqual({a: '1'});
|
expect(t.queryParams).toEqual({a: '1'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reuse old query params when given undefined", () => {
|
it('should reuse old query params when given undefined', () => {
|
||||||
const p = serializer.parse("/?a=1");
|
const p = serializer.parse('/?a=1');
|
||||||
const t = createRoot(p, [], undefined);
|
const t = createRoot(p, [], undefined);
|
||||||
expect(t.queryParams).toEqual({a: '1'});
|
expect(t.queryParams).toEqual({a: '1'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set fragment", () => {
|
it('should set fragment', () => {
|
||||||
const p = serializer.parse("/");
|
const p = serializer.parse('/');
|
||||||
const t = createRoot(p, [], {}, "fragment");
|
const t = createRoot(p, [], {}, 'fragment');
|
||||||
expect(t.fragment).toEqual("fragment");
|
expect(t.fragment).toEqual('fragment');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reused old fragment when given undefined", () => {
|
it('should reused old fragment when given undefined', () => {
|
||||||
const p = serializer.parse("/#fragment");
|
const p = serializer.parse('/#fragment');
|
||||||
const t = createRoot(p, [], undefined, undefined);
|
const t = createRoot(p, [], undefined, undefined);
|
||||||
expect(t.fragment).toEqual("fragment");
|
expect(t.fragment).toEqual('fragment');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
|
function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
|
||||||
const s = new ActivatedRouteSnapshot([], <any>{}, PRIMARY_OUTLET, "someComponent", null, tree.root, -1);
|
const s =
|
||||||
const a = new ActivatedRoute(new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, "someComponent", s);
|
new ActivatedRouteSnapshot([], <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1);
|
||||||
|
const a = new ActivatedRoute(
|
||||||
|
new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s);
|
||||||
advanceActivatedRoute(a);
|
advanceActivatedRoute(a);
|
||||||
return createUrlTree(a, tree, commands, queryParams, fragment);
|
return createUrlTree(a, tree, commands, queryParams, fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(segment: UrlSegment, startIndex: number, tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
|
function create(
|
||||||
|
segment: UrlSegment, startIndex: number, tree: UrlTree, commands: any[], queryParams?: Params,
|
||||||
|
fragment?: string) {
|
||||||
if (!segment) {
|
if (!segment) {
|
||||||
expect(segment).toBeDefined();
|
expect(segment).toBeDefined();
|
||||||
}
|
}
|
||||||
const s = new ActivatedRouteSnapshot([], <any>{}, PRIMARY_OUTLET, "someComponent", null, <any>segment, startIndex);
|
const s = new ActivatedRouteSnapshot(
|
||||||
const a = new ActivatedRoute(new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, "someComponent", s);
|
[], <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment, startIndex);
|
||||||
|
const a = new ActivatedRoute(
|
||||||
|
new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s);
|
||||||
advanceActivatedRoute(a);
|
advanceActivatedRoute(a);
|
||||||
return createUrlTree(a, tree, commands, queryParams, fragment);
|
return createUrlTree(a, tree, commands, queryParams, fragment);
|
||||||
}
|
}
|
|
@ -1,412 +1,433 @@
|
||||||
import {DefaultUrlSerializer} from '../src/url_serializer';
|
|
||||||
import {UrlTree} from '../src/url_tree';
|
|
||||||
import {Params, PRIMARY_OUTLET} from '../src/shared';
|
|
||||||
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../src/router_state';
|
|
||||||
import {RouterConfig} from '../src/config';
|
import {RouterConfig} from '../src/config';
|
||||||
import {recognize} from '../src/recognize';
|
import {recognize} from '../src/recognize';
|
||||||
|
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../src/router_state';
|
||||||
|
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
||||||
|
import {DefaultUrlSerializer} from '../src/url_serializer';
|
||||||
|
import {UrlTree} from '../src/url_tree';
|
||||||
|
|
||||||
describe('recognize', () => {
|
describe('recognize', () => {
|
||||||
it('should work', () => {
|
it('should work', () => {
|
||||||
checkRecognize([
|
checkRecognize([{path: 'a', component: ComponentA}], 'a', (s: RouterStateSnapshot) => {
|
||||||
{
|
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||||
path: 'a', component: ComponentA
|
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
|
||||||
}
|
|
||||||
], "a", (s:RouterStateSnapshot) => {
|
|
||||||
checkActivatedRoute(s.root, "", {}, RootComponent);
|
|
||||||
checkActivatedRoute(s.firstChild(s.root), "a", {}, ComponentA);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support secondary routes', () => {
|
it('should support secondary routes', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{ path: 'a', component: ComponentA },
|
[
|
||||||
{ path: 'b', component: ComponentB, outlet: 'left' },
|
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'left'},
|
||||||
{ path: 'c', component: ComponentC, outlet: 'right' }
|
{path: 'c', component: ComponentC, outlet: 'right'}
|
||||||
], "a(left:b//right:c)", (s:RouterStateSnapshot) => {
|
],
|
||||||
const c = s.children(s.root);
|
'a(left:b//right:c)', (s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(c[0], "a", {}, ComponentA);
|
const c = s.children(s.root);
|
||||||
checkActivatedRoute(c[1], "b", {}, ComponentB, 'left');
|
checkActivatedRoute(c[0], 'a', {}, ComponentA);
|
||||||
checkActivatedRoute(c[2], "c", {}, ComponentC, 'right');
|
checkActivatedRoute(c[1], 'b', {}, ComponentB, 'left');
|
||||||
});
|
checkActivatedRoute(c[2], 'c', {}, ComponentC, 'right');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set url segment and index properly', () => {
|
it('should set url segment and index properly', () => {
|
||||||
const url = tree("a(left:b//right:c)");
|
const url = tree('a(left:b//right:c)');
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{ path: 'a', component: ComponentA },
|
RootComponent,
|
||||||
{ path: 'b', component: ComponentB, outlet: 'left' },
|
[
|
||||||
{ path: 'c', component: ComponentC, outlet: 'right' }
|
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'left'},
|
||||||
], url, "a(left:b//right:c)").subscribe((s) => {
|
{path: 'c', component: ComponentC, outlet: 'right'}
|
||||||
expect(s.root._urlSegment).toBe(url.root);
|
],
|
||||||
expect(s.root._lastPathIndex).toBe(-1);
|
url, 'a(left:b//right:c)')
|
||||||
|
.subscribe((s) => {
|
||||||
|
expect(s.root._urlSegment).toBe(url.root);
|
||||||
|
expect(s.root._lastPathIndex).toBe(-1);
|
||||||
|
|
||||||
const c = s.children(s.root);
|
const c = s.children(s.root);
|
||||||
expect(c[0]._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
expect(c[0]._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
expect(c[0]._lastPathIndex).toBe(0);
|
expect(c[0]._lastPathIndex).toBe(0);
|
||||||
|
|
||||||
expect(c[1]._urlSegment).toBe(url.root.children["left"]);
|
expect(c[1]._urlSegment).toBe(url.root.children['left']);
|
||||||
expect(c[1]._lastPathIndex).toBe(0);
|
expect(c[1]._lastPathIndex).toBe(0);
|
||||||
|
|
||||||
expect(c[2]._urlSegment).toBe(url.root.children["right"]);
|
expect(c[2]._urlSegment).toBe(url.root.children['right']);
|
||||||
expect(c[2]._lastPathIndex).toBe(0);
|
expect(c[2]._lastPathIndex).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set url segment and index properly (nested case)', () => {
|
it('should set url segment and index properly (nested case)', () => {
|
||||||
const url = tree("a/b/c");
|
const url = tree('a/b/c');
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{ path: 'a/b', component: ComponentA, children: [
|
RootComponent,
|
||||||
{path: 'c', component: ComponentC}
|
[
|
||||||
] },
|
{path: 'a/b', component: ComponentA, children: [{path: 'c', component: ComponentC}]},
|
||||||
], url, "a/b/c").subscribe((s:RouterStateSnapshot) => {
|
],
|
||||||
expect(s.root._urlSegment).toBe(url.root);
|
url, 'a/b/c')
|
||||||
expect(s.root._lastPathIndex).toBe(-1);
|
.subscribe((s: RouterStateSnapshot) => {
|
||||||
|
expect(s.root._urlSegment).toBe(url.root);
|
||||||
|
expect(s.root._lastPathIndex).toBe(-1);
|
||||||
|
|
||||||
const compA = s.firstChild(s.root);
|
const compA = s.firstChild(s.root);
|
||||||
expect(compA._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
expect(compA._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
expect(compA._lastPathIndex).toBe(1);
|
expect(compA._lastPathIndex).toBe(1);
|
||||||
|
|
||||||
const compC = s.firstChild(<any>compA);
|
const compC = s.firstChild(<any>compA);
|
||||||
expect(compC._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
expect(compC._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
expect(compC._lastPathIndex).toBe(2);
|
expect(compC._lastPathIndex).toBe(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should match routes in the depth first order', () => {
|
it('should match routes in the depth first order', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{path: 'a', component: ComponentA, children: [{path: ':id', component: ComponentB}]},
|
[
|
||||||
{path: 'a/:id', component: ComponentC}
|
{path: 'a', component: ComponentA, children: [{path: ':id', component: ComponentB}]},
|
||||||
], "a/paramA", (s:RouterStateSnapshot) => {
|
{path: 'a/:id', component: ComponentC}
|
||||||
checkActivatedRoute(s.root, "", {}, RootComponent);
|
],
|
||||||
checkActivatedRoute(s.firstChild(s.root), "a", {}, ComponentA);
|
'a/paramA', (s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), "paramA", {id: 'paramA'}, ComponentB);
|
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||||
});
|
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
|
||||||
|
checkActivatedRoute(
|
||||||
|
s.firstChild(<any>s.firstChild(s.root)), 'paramA', {id: 'paramA'}, ComponentB);
|
||||||
|
});
|
||||||
|
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{path: 'a', component: ComponentA},
|
[{path: 'a', component: ComponentA}, {path: 'a/:id', component: ComponentC}], 'a/paramA',
|
||||||
{path: 'a/:id', component: ComponentC}
|
(s: RouterStateSnapshot) => {
|
||||||
], "a/paramA", (s:RouterStateSnapshot) => {
|
checkActivatedRoute(s.root, '', {}, RootComponent);
|
||||||
checkActivatedRoute(s.root, "", {}, RootComponent);
|
checkActivatedRoute(s.firstChild(s.root), 'a/paramA', {id: 'paramA'}, ComponentC);
|
||||||
checkActivatedRoute(s.firstChild(s.root), "a/paramA", {id: 'paramA'}, ComponentC);
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use outlet name when matching secondary routes', () => {
|
it('should use outlet name when matching secondary routes', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{ path: 'a', component: ComponentA },
|
[
|
||||||
{ path: 'b', component: ComponentB, outlet: 'left' },
|
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'left'},
|
||||||
{ path: 'b', component: ComponentC, outlet: 'right' }
|
{path: 'b', component: ComponentC, outlet: 'right'}
|
||||||
], "a(right:b)", (s:RouterStateSnapshot) => {
|
],
|
||||||
const c = s.children(s.root);
|
'a(right:b)', (s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(c[0], "a", {}, ComponentA);
|
const c = s.children(s.root);
|
||||||
checkActivatedRoute(c[1], "b", {}, ComponentC, 'right');
|
checkActivatedRoute(c[0], 'a', {}, ComponentA);
|
||||||
});
|
checkActivatedRoute(c[1], 'b', {}, ComponentC, 'right');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('should handle nested secondary routes', () => {
|
xit('should handle nested secondary routes', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{ path: 'a', component: ComponentA },
|
[
|
||||||
{ path: 'b', component: ComponentB, outlet: 'left' },
|
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'left'},
|
||||||
{ path: 'c', component: ComponentC, outlet: 'right' }
|
{path: 'c', component: ComponentC, outlet: 'right'}
|
||||||
], "a(left:b(right:c))", (s:RouterStateSnapshot) => {
|
],
|
||||||
const c = s.children(s.root);
|
'a(left:b(right:c))', (s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(c[0], "a", {}, ComponentA);
|
const c = s.children(s.root);
|
||||||
checkActivatedRoute(c[1], "b", {}, ComponentB, 'left');
|
checkActivatedRoute(c[0], 'a', {}, ComponentA);
|
||||||
checkActivatedRoute(c[2], "c", {}, ComponentC, 'right');
|
checkActivatedRoute(c[1], 'b', {}, ComponentB, 'left');
|
||||||
});
|
checkActivatedRoute(c[2], 'c', {}, ComponentC, 'right');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle non top-level secondary routes', () => {
|
it('should handle non top-level secondary routes', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{ path: 'a', component: ComponentA, children: [
|
[
|
||||||
{ path: 'b', component: ComponentB },
|
{
|
||||||
{ path: 'c', component: ComponentC, outlet: 'left' }
|
path: 'a',
|
||||||
] },
|
component: ComponentA,
|
||||||
], "a/(b//left:c)", (s:RouterStateSnapshot) => {
|
children: [
|
||||||
const c = s.children(<any>s.firstChild(s.root));
|
{path: 'b', component: ComponentB},
|
||||||
checkActivatedRoute(c[0], "b", {}, ComponentB, PRIMARY_OUTLET);
|
{path: 'c', component: ComponentC, outlet: 'left'}
|
||||||
checkActivatedRoute(c[1], "c", {}, ComponentC, 'left');
|
]
|
||||||
});
|
},
|
||||||
|
],
|
||||||
|
'a/(b//left:c)', (s: RouterStateSnapshot) => {
|
||||||
|
const c = s.children(<any>s.firstChild(s.root));
|
||||||
|
checkActivatedRoute(c[0], 'b', {}, ComponentB, PRIMARY_OUTLET);
|
||||||
|
checkActivatedRoute(c[1], 'c', {}, ComponentC, 'left');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sort routes by outlet name', () => {
|
it('should sort routes by outlet name', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{ path: 'a', component: ComponentA },
|
[
|
||||||
{ path: 'c', component: ComponentC, outlet: 'c' },
|
{path: 'a', component: ComponentA}, {path: 'c', component: ComponentC, outlet: 'c'},
|
||||||
{ path: 'b', component: ComponentB, outlet: 'b' }
|
{path: 'b', component: ComponentB, outlet: 'b'}
|
||||||
], "a(c:c//b:b)", (s:RouterStateSnapshot) => {
|
],
|
||||||
const c = s.children(s.root);
|
'a(c:c//b:b)', (s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(c[0], "a", {}, ComponentA);
|
const c = s.children(s.root);
|
||||||
checkActivatedRoute(c[1], "b", {}, ComponentB, 'b');
|
checkActivatedRoute(c[0], 'a', {}, ComponentA);
|
||||||
checkActivatedRoute(c[2], "c", {}, ComponentC, 'c');
|
checkActivatedRoute(c[1], 'b', {}, ComponentB, 'b');
|
||||||
});
|
checkActivatedRoute(c[2], 'c', {}, ComponentC, 'c');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support matrix parameters', () => {
|
it('should support matrix parameters', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{
|
[
|
||||||
path: 'a', component: ComponentA, children: [
|
{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]},
|
||||||
{ path: 'b', component: ComponentB }
|
{path: 'c', component: ComponentC, outlet: 'left'}
|
||||||
]
|
],
|
||||||
},
|
'a;a1=11;a2=22/b;b1=111;b2=222(left:c;c1=1111;c2=2222)', (s: RouterStateSnapshot) => {
|
||||||
{ path: 'c', component: ComponentC, outlet: 'left' }
|
const c = s.children(s.root);
|
||||||
], "a;a1=11;a2=22/b;b1=111;b2=222(left:c;c1=1111;c2=2222)", (s:RouterStateSnapshot) => {
|
checkActivatedRoute(c[0], 'a', {a1: '11', a2: '22'}, ComponentA);
|
||||||
const c = s.children(s.root);
|
checkActivatedRoute(s.firstChild(<any>c[0]), 'b', {b1: '111', b2: '222'}, ComponentB);
|
||||||
checkActivatedRoute(c[0], "a", {a1: '11', a2: '22'}, ComponentA);
|
checkActivatedRoute(c[1], 'c', {c1: '1111', c2: '2222'}, ComponentC, 'left');
|
||||||
checkActivatedRoute(s.firstChild(<any>c[0]), "b", {b1: '111', b2: '222'}, ComponentB);
|
});
|
||||||
checkActivatedRoute(c[1], "c", {c1: '1111', c2: '2222'}, ComponentC, 'left');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("matching empty url", () => {
|
describe('matching empty url', () => {
|
||||||
it("should support root index routes", () => {
|
it('should support root index routes', () => {
|
||||||
recognize(RootComponent, [
|
recognize(RootComponent, [{path: '', component: ComponentA}], tree(''), '')
|
||||||
{path: '', component: ComponentA}
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
], tree(""), "").forEach((s:RouterStateSnapshot) => {
|
checkActivatedRoute(s.firstChild(s.root), '', {}, ComponentA);
|
||||||
checkActivatedRoute(s.firstChild(s.root), "", {}, ComponentA);
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support nested root index routes", () => {
|
it('should support nested root index routes', () => {
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{path: '', component: ComponentA, children: [{path: '', component: ComponentB}]}
|
RootComponent,
|
||||||
], tree(""), "").forEach((s:RouterStateSnapshot) => {
|
[{path: '', component: ComponentA, children: [{path: '', component: ComponentB}]}],
|
||||||
checkActivatedRoute(s.firstChild(s.root), "", {}, ComponentA);
|
tree(''), '')
|
||||||
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), "", {}, ComponentB);
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
});
|
checkActivatedRoute(s.firstChild(s.root), '', {}, ComponentA);
|
||||||
|
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), '', {}, ComponentB);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set url segment and index properly', () => {
|
it('should set url segment and index properly', () => {
|
||||||
const url = tree("");
|
const url = tree('');
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{path: '', component: ComponentA, children: [{path: '', component: ComponentB}]}
|
RootComponent,
|
||||||
], url, "").forEach((s:RouterStateSnapshot) => {
|
[{path: '', component: ComponentA, children: [{path: '', component: ComponentB}]}], url,
|
||||||
expect(s.root._urlSegment).toBe(url.root);
|
'')
|
||||||
expect(s.root._lastPathIndex).toBe(-1);
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
|
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._urlSegment).toBe(url.root);
|
||||||
expect(c._lastPathIndex).toBe(-1);
|
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._urlSegment).toBe(url.root);
|
||||||
expect(c2._lastPathIndex).toBe(-1);
|
expect(c2._lastPathIndex).toBe(-1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support index routes", () => {
|
it('should support index routes', () => {
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{path: 'a', component: ComponentA, children: [
|
RootComponent,
|
||||||
{path: '', component: ComponentB}
|
[{path: 'a', component: ComponentA, children: [{path: '', component: ComponentB}]}],
|
||||||
]}
|
tree('a'), 'a')
|
||||||
], tree("a"), "a").forEach((s:RouterStateSnapshot) => {
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(s.firstChild(s.root), "a", {}, ComponentA);
|
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
|
||||||
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), "", {}, ComponentB);
|
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), '', {}, ComponentB);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support index routes with children", () => {
|
it('should support index routes with children', () => {
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{
|
RootComponent, [{
|
||||||
path: '', component: ComponentA, children: [
|
path: '',
|
||||||
{ path: '', component: ComponentB, children: [
|
component: ComponentA,
|
||||||
{path: 'c/:id', component: ComponentC}
|
children: [{
|
||||||
]
|
path: '',
|
||||||
}
|
component: ComponentB,
|
||||||
]
|
children: [{path: 'c/:id', component: ComponentC}]
|
||||||
}
|
}]
|
||||||
], tree("c/10"), "c/10").forEach((s:RouterStateSnapshot) => {
|
}],
|
||||||
checkActivatedRoute(s.firstChild(s.root), "", {}, ComponentA);
|
tree('c/10'), 'c/10')
|
||||||
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), "", {}, ComponentB);
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(
|
checkActivatedRoute(s.firstChild(s.root), '', {}, ComponentA);
|
||||||
s.firstChild(<any>s.firstChild(<any>s.firstChild(s.root))), "c/10", {id: '10'}, ComponentC);
|
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), '', {}, ComponentB);
|
||||||
});
|
checkActivatedRoute(
|
||||||
|
s.firstChild(<any>s.firstChild(<any>s.firstChild(s.root))), 'c/10', {id: '10'},
|
||||||
|
ComponentC);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should pass parameters to every nested index route (case with non-index route)", () => {
|
xit('should pass parameters to every nested index route (case with non-index route)', () => {
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{path: 'a', component: ComponentA, children: [{path: '', component: ComponentB}]}
|
RootComponent,
|
||||||
], tree("/a;a=1"), "/a;a=1").forEach((s:RouterStateSnapshot) => {
|
[{path: 'a', component: ComponentA, children: [{path: '', component: ComponentB}]}],
|
||||||
checkActivatedRoute(s.firstChild(s.root), "a", {a: '1'}, ComponentA);
|
tree('/a;a=1'), '/a;a=1')
|
||||||
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), "", {a: '1'}, ComponentB);
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
});
|
checkActivatedRoute(s.firstChild(s.root), 'a', {a: '1'}, ComponentA);
|
||||||
|
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), '', {a: '1'}, ComponentB);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("wildcards", () => {
|
describe('wildcards', () => {
|
||||||
it("should support simple wildcards", () => {
|
it('should support simple wildcards', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{path: '**', component: ComponentA}
|
[{path: '**', component: ComponentA}], 'a/b/c/d;a1=11', (s: RouterStateSnapshot) => {
|
||||||
], "a/b/c/d;a1=11", (s:RouterStateSnapshot) => {
|
checkActivatedRoute(s.firstChild(s.root), 'a/b/c/d', {a1: '11'}, ComponentA);
|
||||||
checkActivatedRoute(s.firstChild(s.root), "a/b/c/d", {a1:'11'}, ComponentA);
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("componentless routes", () => {
|
describe('componentless routes', () => {
|
||||||
it("should work", () => {
|
it('should work', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{
|
[{
|
||||||
path: 'p/:id',
|
path: 'p/:id',
|
||||||
children: [
|
children: [
|
||||||
{path: 'a', component: ComponentA},
|
{path: 'a', component: ComponentA},
|
||||||
{path: 'b', component: ComponentB, outlet: 'aux'}
|
{path: 'b', component: ComponentB, outlet: 'aux'}
|
||||||
]
|
]
|
||||||
}
|
}],
|
||||||
], "p/11;pp=22/(a;pa=33//aux:b;pb=44)", (s:RouterStateSnapshot) => {
|
'p/11;pp=22/(a;pa=33//aux:b;pb=44)', (s: RouterStateSnapshot) => {
|
||||||
const p = s.firstChild(s.root);
|
const p = s.firstChild(s.root);
|
||||||
checkActivatedRoute(p, "p/11", {id: '11', pp: '22'}, undefined);
|
checkActivatedRoute(p, 'p/11', {id: '11', pp: '22'}, undefined);
|
||||||
|
|
||||||
const c = s.children(p);
|
const c = s.children(p);
|
||||||
checkActivatedRoute(c[0], "a", {id: '11', pp: '22', pa: '33'}, ComponentA);
|
checkActivatedRoute(c[0], 'a', {id: '11', pp: '22', pa: '33'}, ComponentA);
|
||||||
checkActivatedRoute(c[1], "b", {id: '11', pp: '22', pb: '44'}, ComponentB, "aux");
|
checkActivatedRoute(c[1], 'b', {id: '11', pp: '22', pb: '44'}, ComponentB, 'aux');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should merge params until encounters a normal route", () => {
|
it('should merge params until encounters a normal route', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{
|
[{
|
||||||
path: 'p/:id',
|
path: 'p/:id',
|
||||||
children: [
|
children: [{
|
||||||
{path: 'a/:name', children: [
|
path: 'a/:name',
|
||||||
{path: 'b', component: ComponentB, children: [
|
children: [{
|
||||||
{path: 'c', component: ComponentC}
|
path: 'b',
|
||||||
]}
|
component: ComponentB,
|
||||||
]}
|
children: [{path: 'c', component: ComponentC}]
|
||||||
]
|
}]
|
||||||
}
|
}]
|
||||||
], "p/11/a/victor/b/c", (s:RouterStateSnapshot) => {
|
}],
|
||||||
const p = s.firstChild(s.root);
|
'p/11/a/victor/b/c', (s: RouterStateSnapshot) => {
|
||||||
checkActivatedRoute(p, "p/11", {id: '11'}, undefined);
|
const p = s.firstChild(s.root);
|
||||||
|
checkActivatedRoute(p, 'p/11', {id: '11'}, undefined);
|
||||||
|
|
||||||
const a = s.firstChild(p);
|
const a = s.firstChild(p);
|
||||||
checkActivatedRoute(a, "a/victor", {id: '11', name: 'victor'}, undefined);
|
checkActivatedRoute(a, 'a/victor', {id: '11', name: 'victor'}, undefined);
|
||||||
|
|
||||||
const b = s.firstChild(a);
|
const b = s.firstChild(a);
|
||||||
checkActivatedRoute(b, "b", {id: '11', name: 'victor'}, ComponentB);
|
checkActivatedRoute(b, 'b', {id: '11', name: 'victor'}, ComponentB);
|
||||||
|
|
||||||
const c = s.firstChild(b);
|
const c = s.firstChild(b);
|
||||||
checkActivatedRoute(c, "c", {}, ComponentC);
|
checkActivatedRoute(c, 'c', {}, ComponentC);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should work with empty paths", () => {
|
xit('should work with empty paths', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{
|
[{
|
||||||
path: 'p/:id',
|
path: 'p/:id',
|
||||||
children: [
|
children: [
|
||||||
{path: '', component: ComponentA},
|
{path: '', component: ComponentA},
|
||||||
{path: '', component: ComponentB, outlet: 'aux'}
|
{path: '', component: ComponentB, outlet: 'aux'}
|
||||||
]
|
]
|
||||||
}
|
}],
|
||||||
], "p/11", (s:RouterStateSnapshot) => {
|
'p/11', (s: RouterStateSnapshot) => {
|
||||||
const p = s.firstChild(s.root);
|
const p = s.firstChild(s.root);
|
||||||
checkActivatedRoute(p, "p/11", {id: '11'}, undefined);
|
checkActivatedRoute(p, 'p/11', {id: '11'}, undefined);
|
||||||
|
|
||||||
const c = s.children(p);
|
const c = s.children(p);
|
||||||
console.log("lsfs", c);
|
console.log('lsfs', c);
|
||||||
checkActivatedRoute(c[0], "", {}, ComponentA);
|
checkActivatedRoute(c[0], '', {}, ComponentA);
|
||||||
checkActivatedRoute(c[1], "", {}, ComponentB, "aux");
|
checkActivatedRoute(c[1], '', {}, ComponentB, 'aux');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should work with empty paths and params", () => {
|
xit('should work with empty paths and params', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{
|
[{
|
||||||
path: 'p/:id',
|
path: 'p/:id',
|
||||||
children: [
|
children: [
|
||||||
{path: '', component: ComponentA},
|
{path: '', component: ComponentA},
|
||||||
{path: '', component: ComponentB, outlet: 'aux'}
|
{path: '', component: ComponentB, outlet: 'aux'}
|
||||||
]
|
]
|
||||||
}
|
}],
|
||||||
], "p/11/(;pa=33//aux:;pb=44)", (s:RouterStateSnapshot) => {
|
'p/11/(;pa=33//aux:;pb=44)', (s: RouterStateSnapshot) => {
|
||||||
const p = s.firstChild(s.root);
|
const p = s.firstChild(s.root);
|
||||||
checkActivatedRoute(p, "p/11", {id: '11'}, undefined);
|
checkActivatedRoute(p, 'p/11', {id: '11'}, undefined);
|
||||||
|
|
||||||
const c = s.children(p);
|
const c = s.children(p);
|
||||||
checkActivatedRoute(c[0], "", {pa: '33'}, ComponentA);
|
checkActivatedRoute(c[0], '', {pa: '33'}, ComponentA);
|
||||||
checkActivatedRoute(c[1], "", {pb: '44'}, ComponentB, "aux");
|
checkActivatedRoute(c[1], '', {pb: '44'}, ComponentB, 'aux');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should work with only aux path", () => {
|
xit('should work with only aux path', () => {
|
||||||
checkRecognize([
|
checkRecognize(
|
||||||
{
|
[{
|
||||||
path: 'p/:id',
|
path: 'p/:id',
|
||||||
children: [
|
children: [
|
||||||
{path: '', component: ComponentA},
|
{path: '', component: ComponentA},
|
||||||
{path: '', component: ComponentB, outlet: 'aux'}
|
{path: '', component: ComponentB, outlet: 'aux'}
|
||||||
]
|
]
|
||||||
}
|
}],
|
||||||
], "p/11", (s:RouterStateSnapshot) => {
|
'p/11', (s: RouterStateSnapshot) => {
|
||||||
const p = s.firstChild(s.root);
|
const p = s.firstChild(s.root);
|
||||||
checkActivatedRoute(p, "p/11(aux:;pb=44)", {id: '11'}, undefined);
|
checkActivatedRoute(p, 'p/11(aux:;pb=44)', {id: '11'}, undefined);
|
||||||
|
|
||||||
const c = s.children(p);
|
const c = s.children(p);
|
||||||
checkActivatedRoute(c[0], "", {}, ComponentA);
|
checkActivatedRoute(c[0], '', {}, ComponentA);
|
||||||
checkActivatedRoute(c[1], "", {pb: '44'}, ComponentB, "aux");
|
checkActivatedRoute(c[1], '', {pb: '44'}, ComponentB, 'aux');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("query parameters", () => {
|
describe('query parameters', () => {
|
||||||
it("should support query params", () => {
|
it('should support query params', () => {
|
||||||
const config = [{path: 'a', component: ComponentA}];
|
const config = [{path: 'a', component: ComponentA}];
|
||||||
checkRecognize(config, "a?q=11", (s:RouterStateSnapshot) => {
|
checkRecognize(config, 'a?q=11', (s: RouterStateSnapshot) => {
|
||||||
expect(s.queryParams).toEqual({q: '11'});
|
expect(s.queryParams).toEqual({q: '11'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("fragment", () => {
|
describe('fragment', () => {
|
||||||
it("should support fragment", () => {
|
it('should support fragment', () => {
|
||||||
const config = [{path: 'a', component: ComponentA}];
|
const config = [{path: 'a', component: ComponentA}];
|
||||||
checkRecognize(config, "a#f1", (s:RouterStateSnapshot) => {
|
checkRecognize(
|
||||||
expect(s.fragment).toEqual("f1");
|
config, 'a#f1', (s: RouterStateSnapshot) => { expect(s.fragment).toEqual('f1'); });
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("error handling", () => {
|
describe('error handling', () => {
|
||||||
it('should error when two routes with the same outlet name got matched', () => {
|
it('should error when two routes with the same outlet name got matched', () => {
|
||||||
recognize(RootComponent, [
|
recognize(
|
||||||
{ path: 'a', component: ComponentA },
|
RootComponent,
|
||||||
{ path: 'b', component: ComponentB, outlet: 'aux' },
|
[
|
||||||
{ path: 'c', component: ComponentC, outlet: 'aux' }
|
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'aux'},
|
||||||
], tree("a(aux:b//aux:c)"), "a(aux:b//aux:c)").subscribe((_) => {}, (s:RouterStateSnapshot) => {
|
{path: 'c', component: ComponentC, outlet: 'aux'}
|
||||||
expect(s.toString()).toContain("Two segments cannot have the same outlet name: 'aux:b' and 'aux:c'.");
|
],
|
||||||
});
|
tree('a(aux:b//aux:c)'), 'a(aux:b//aux:c)')
|
||||||
|
.subscribe((_) => {}, (s: RouterStateSnapshot) => {
|
||||||
|
expect(s.toString())
|
||||||
|
.toContain(
|
||||||
|
'Two segments cannot have the same outlet name: \'aux:b\' and \'aux:c\'.');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should error when no matching routes", () => {
|
it('should error when no matching routes', () => {
|
||||||
recognize(RootComponent, [
|
recognize(RootComponent, [{path: 'a', component: ComponentA}], tree('invalid'), 'invalid')
|
||||||
{ path: 'a', component: ComponentA }
|
.subscribe((_) => {}, (s: RouterStateSnapshot) => {
|
||||||
], tree("invalid"), "invalid").subscribe((_) => {}, (s:RouterStateSnapshot) => {
|
expect(s.toString()).toContain('Cannot match any routes');
|
||||||
expect(s.toString()).toContain("Cannot match any routes");
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should error when no matching routes (too short)", () => {
|
it('should error when no matching routes (too short)', () => {
|
||||||
recognize(RootComponent, [
|
recognize(RootComponent, [{path: 'a/:id', component: ComponentA}], tree('a'), 'a')
|
||||||
{ path: 'a/:id', component: ComponentA }
|
.subscribe((_) => {}, (s: RouterStateSnapshot) => {
|
||||||
], tree("a"), "a").subscribe((_) => {}, (s:RouterStateSnapshot) => {
|
expect(s.toString()).toContain('Cannot match any routes');
|
||||||
expect(s.toString()).toContain("Cannot match any routes");
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkRecognize(config: RouterConfig, url: string, callback: any): void {
|
function checkRecognize(config: RouterConfig, url: string, callback: any): void {
|
||||||
recognize(RootComponent, config, tree(url), url).subscribe(callback, e => {
|
recognize(RootComponent, config, tree(url), url).subscribe(callback, e => { throw e; });
|
||||||
throw e;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkActivatedRoute(actual: ActivatedRouteSnapshot, url: string, params: Params, cmp: Function, outlet: string = PRIMARY_OUTLET):void {
|
function checkActivatedRoute(
|
||||||
|
actual: ActivatedRouteSnapshot, url: string, params: Params, cmp: Function,
|
||||||
|
outlet: string = PRIMARY_OUTLET): void {
|
||||||
if (actual === null) {
|
if (actual === null) {
|
||||||
expect(actual).not.toBeNull();
|
expect(actual).not.toBeNull();
|
||||||
} else {
|
} else {
|
||||||
expect(actual.url.map(s => s.path).join("/")).toEqual(url);
|
expect(actual.url.map(s => s.path).join('/')).toEqual(url);
|
||||||
expect(actual.params).toEqual(params);
|
expect(actual.params).toEqual(params);
|
||||||
expect(actual.component).toBe(cmp);
|
expect(actual.component).toBe(cmp);
|
||||||
expect(actual.outlet).toEqual(outlet);
|
expect(actual.outlet).toEqual(outlet);
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
import {DefaultUrlSerializer} from '../src/url_serializer';
|
import {RouterConfig} from '../src/config';
|
||||||
import {UrlTree, UrlSegment} from '../src/url_tree';
|
|
||||||
import {RouterStateSnapshot} from '../src/router_state';
|
|
||||||
import {recognize} from '../src/recognize';
|
import {recognize} from '../src/recognize';
|
||||||
import {resolve} from '../src/resolve';
|
import {resolve} from '../src/resolve';
|
||||||
import {RouterConfig} from '../src/config';
|
import {RouterStateSnapshot} from '../src/router_state';
|
||||||
|
import {DefaultUrlSerializer} from '../src/url_serializer';
|
||||||
|
import {UrlSegment, UrlTree} from '../src/url_tree';
|
||||||
|
|
||||||
describe('resolve', () => {
|
describe('resolve', () => {
|
||||||
it('should resolve components', () => {
|
it('should resolve components', () => {
|
||||||
checkResolve([
|
checkResolve(
|
||||||
{path: 'a', component: "ComponentA"}
|
[{path: 'a', component: 'ComponentA'}], 'a', {ComponentA: 'ResolvedComponentA'},
|
||||||
], "a", {ComponentA: 'ResolvedComponentA'}, (resolved:RouterStateSnapshot) => {
|
(resolved: RouterStateSnapshot) => {
|
||||||
expect(resolved.firstChild(resolved.root)._resolvedComponentFactory).toEqual('ResolvedComponentA');
|
expect(resolved.firstChild(resolved.root)._resolvedComponentFactory)
|
||||||
});
|
.toEqual('ResolvedComponentA');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not resolve componentless routes', () => {
|
it('should not resolve componentless routes', () => {
|
||||||
checkResolve([
|
checkResolve([{path: 'a', children: []}], 'a', {}, (resolved: RouterStateSnapshot) => {
|
||||||
{path: 'a', children: []}
|
|
||||||
], "a", {}, (resolved:RouterStateSnapshot) => {
|
|
||||||
expect(resolved.firstChild(resolved.root)._resolvedComponentFactory).toEqual(null);
|
expect(resolved.firstChild(resolved.root)._resolvedComponentFactory).toEqual(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkResolve(config: RouterConfig, url: string, resolved: {[k:string]:string}, callback: any): void {
|
function checkResolve(
|
||||||
|
config: RouterConfig, url: string, resolved: {[k: string]: string}, callback: any): void {
|
||||||
const resolver = {
|
const resolver = {
|
||||||
resolveComponent: (component:string):Promise<any> => {
|
resolveComponent: (component: string): Promise<any> => {
|
||||||
if (resolved[component]) {
|
if (resolved[component]) {
|
||||||
return Promise.resolve(resolved[component]);
|
return Promise.resolve(resolved[component]);
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject("unknown component");
|
return Promise.reject('unknown component');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
recognize(RootComponent, config, tree(url), url).mergeMap(s => resolve(<any>resolver, s)).subscribe(callback, e => {
|
recognize(RootComponent, config, tree(url), url)
|
||||||
throw e;
|
.mergeMap(s => resolve(<any>resolver, s))
|
||||||
});
|
.subscribe(callback, e => { throw e; });
|
||||||
}
|
}
|
||||||
|
|
||||||
function tree(url: string): UrlTree {
|
function tree(url: string): UrlTree {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,38 +1,38 @@
|
||||||
|
import {PRIMARY_OUTLET} from '../src/shared';
|
||||||
import {DefaultUrlSerializer, serializePath} from '../src/url_serializer';
|
import {DefaultUrlSerializer, serializePath} from '../src/url_serializer';
|
||||||
import {UrlSegment} from '../src/url_tree';
|
import {UrlSegment} from '../src/url_tree';
|
||||||
import {PRIMARY_OUTLET} from '../src/shared';
|
|
||||||
|
|
||||||
describe('url serializer', () => {
|
describe('url serializer', () => {
|
||||||
const url = new DefaultUrlSerializer();
|
const url = new DefaultUrlSerializer();
|
||||||
|
|
||||||
it('should parse the root url', () => {
|
it('should parse the root url', () => {
|
||||||
const tree = url.parse("/");
|
const tree = url.parse('/');
|
||||||
|
|
||||||
expectSegment(tree.root, "");
|
expectSegment(tree.root, '');
|
||||||
expect(url.serialize(tree)).toEqual("/");
|
expect(url.serialize(tree)).toEqual('/');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse non-empty urls', () => {
|
it('should parse non-empty urls', () => {
|
||||||
const tree = url.parse("one/two");
|
const tree = url.parse('one/two');
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one/two");
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one/two');
|
||||||
expect(url.serialize(tree)).toEqual("/one/two");
|
expect(url.serialize(tree)).toEqual('/one/two');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse multiple secondary segments", () => {
|
it('should parse multiple secondary segments', () => {
|
||||||
const tree = url.parse("/one/two(left:three//right:four)");
|
const tree = url.parse('/one/two(left:three//right:four)');
|
||||||
|
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one/two");
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one/two');
|
||||||
expectSegment(tree.root.children['left'], "three");
|
expectSegment(tree.root.children['left'], 'three');
|
||||||
expectSegment(tree.root.children['right'], "four");
|
expectSegment(tree.root.children['right'], 'four');
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one/two(left:three//right:four)");
|
expect(url.serialize(tree)).toEqual('/one/two(left:three//right:four)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse segments with empty paths", () => {
|
it('should parse segments with empty paths', () => {
|
||||||
const tree = url.parse("/one/two/(;a=1//right:;b=2)");
|
const tree = url.parse('/one/two/(;a=1//right:;b=2)');
|
||||||
|
|
||||||
const c = tree.root.children[PRIMARY_OUTLET];
|
const c = tree.root.children[PRIMARY_OUTLET];
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one/two", true);
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one/two', true);
|
||||||
|
|
||||||
expect(c.children[PRIMARY_OUTLET].pathsWithParams[0].path).toEqual('');
|
expect(c.children[PRIMARY_OUTLET].pathsWithParams[0].path).toEqual('');
|
||||||
expect(c.children[PRIMARY_OUTLET].pathsWithParams[0].parameters).toEqual({a: '1'});
|
expect(c.children[PRIMARY_OUTLET].pathsWithParams[0].parameters).toEqual({a: '1'});
|
||||||
|
@ -40,115 +40,115 @@ describe('url serializer', () => {
|
||||||
expect(c.children['right'].pathsWithParams[0].path).toEqual('');
|
expect(c.children['right'].pathsWithParams[0].path).toEqual('');
|
||||||
expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'});
|
expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'});
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one/two/(;a=1//right:;b=2)");
|
expect(url.serialize(tree)).toEqual('/one/two/(;a=1//right:;b=2)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse segments with empty paths (only aux)", () => {
|
it('should parse segments with empty paths (only aux)', () => {
|
||||||
const tree = url.parse("/one/two/(right:;b=2)");
|
const tree = url.parse('/one/two/(right:;b=2)');
|
||||||
|
|
||||||
const c = tree.root.children[PRIMARY_OUTLET];
|
const c = tree.root.children[PRIMARY_OUTLET];
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one/two", true);
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one/two', true);
|
||||||
|
|
||||||
expect(c.children['right'].pathsWithParams[0].path).toEqual('');
|
expect(c.children['right'].pathsWithParams[0].path).toEqual('');
|
||||||
expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'});
|
expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'});
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one/two/(right:;b=2)");
|
expect(url.serialize(tree)).toEqual('/one/two/(right:;b=2)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse scoped secondary segments", () => {
|
it('should parse scoped secondary segments', () => {
|
||||||
const tree = url.parse("/one/(two//left:three)");
|
const tree = url.parse('/one/(two//left:three)');
|
||||||
|
|
||||||
const primary = tree.root.children[PRIMARY_OUTLET];
|
const primary = tree.root.children[PRIMARY_OUTLET];
|
||||||
expectSegment(primary, "one", true);
|
expectSegment(primary, 'one', true);
|
||||||
|
|
||||||
expectSegment(primary.children[PRIMARY_OUTLET], "two");
|
expectSegment(primary.children[PRIMARY_OUTLET], 'two');
|
||||||
expectSegment(primary.children["left"], "three");
|
expectSegment(primary.children['left'], 'three');
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one/(two//left:three)");
|
expect(url.serialize(tree)).toEqual('/one/(two//left:three)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse scoped secondary segments with unscoped ones", () => {
|
it('should parse scoped secondary segments with unscoped ones', () => {
|
||||||
const tree = url.parse("/one/(two//left:three)(right:four)");
|
const tree = url.parse('/one/(two//left:three)(right:four)');
|
||||||
|
|
||||||
const primary = tree.root.children[PRIMARY_OUTLET];
|
const primary = tree.root.children[PRIMARY_OUTLET];
|
||||||
expectSegment(primary, "one", true);
|
expectSegment(primary, 'one', true);
|
||||||
expectSegment(primary.children[PRIMARY_OUTLET], "two");
|
expectSegment(primary.children[PRIMARY_OUTLET], 'two');
|
||||||
expectSegment(primary.children["left"], "three");
|
expectSegment(primary.children['left'], 'three');
|
||||||
expectSegment(tree.root.children["right"], "four");
|
expectSegment(tree.root.children['right'], 'four');
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one/(two//left:three)(right:four)");
|
expect(url.serialize(tree)).toEqual('/one/(two//left:three)(right:four)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse secondary segments that have children", () => {
|
it('should parse secondary segments that have children', () => {
|
||||||
const tree = url.parse("/one(left:two/three)");
|
const tree = url.parse('/one(left:two/three)');
|
||||||
|
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one");
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one');
|
||||||
expectSegment(tree.root.children['left'], "two/three");
|
expectSegment(tree.root.children['left'], 'two/three');
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one(left:two/three)");
|
expect(url.serialize(tree)).toEqual('/one(left:two/three)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse an empty secondary segment group", () => {
|
it('should parse an empty secondary segment group', () => {
|
||||||
const tree = url.parse("/one()");
|
const tree = url.parse('/one()');
|
||||||
|
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one");
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one');
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one");
|
expect(url.serialize(tree)).toEqual('/one');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse key-value matrix params", () => {
|
it('should parse key-value matrix params', () => {
|
||||||
const tree = url.parse("/one;a=11a;b=11b(left:two;c=22//right:three;d=33)");
|
const tree = url.parse('/one;a=11a;b=11b(left:two;c=22//right:three;d=33)');
|
||||||
|
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one;a=11a;b=11b");
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one;a=11a;b=11b');
|
||||||
expectSegment(tree.root.children["left"], "two;c=22");
|
expectSegment(tree.root.children['left'], 'two;c=22');
|
||||||
expectSegment(tree.root.children["right"], "three;d=33");
|
expectSegment(tree.root.children['right'], 'three;d=33');
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one;a=11a;b=11b(left:two;c=22//right:three;d=33)");
|
expect(url.serialize(tree)).toEqual('/one;a=11a;b=11b(left:two;c=22//right:three;d=33)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse key only matrix params", () => {
|
it('should parse key only matrix params', () => {
|
||||||
const tree = url.parse("/one;a");
|
const tree = url.parse('/one;a');
|
||||||
|
|
||||||
expectSegment(tree.root.children[PRIMARY_OUTLET], "one;a=true");
|
expectSegment(tree.root.children[PRIMARY_OUTLET], 'one;a=true');
|
||||||
|
|
||||||
expect(url.serialize(tree)).toEqual("/one;a=true");
|
expect(url.serialize(tree)).toEqual('/one;a=true');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse query params", () => {
|
it('should parse query params', () => {
|
||||||
const tree = url.parse("/one?a=1&b=2");
|
const tree = url.parse('/one?a=1&b=2');
|
||||||
expect(tree.queryParams).toEqual({a: '1', b: '2'});
|
expect(tree.queryParams).toEqual({a: '1', b: '2'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse query params when with parenthesis", () => {
|
it('should parse query params when with parenthesis', () => {
|
||||||
const tree = url.parse("/one?a=(11)&b=(22)");
|
const tree = url.parse('/one?a=(11)&b=(22)');
|
||||||
expect(tree.queryParams).toEqual({a: '(11)', b: '(22)'});
|
expect(tree.queryParams).toEqual({a: '(11)', b: '(22)'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse key only query params", () => {
|
it('should parse key only query params', () => {
|
||||||
const tree = url.parse("/one?a");
|
const tree = url.parse('/one?a');
|
||||||
expect(tree.queryParams).toEqual({a: 'true'});
|
expect(tree.queryParams).toEqual({a: 'true'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should serializer query params", () => {
|
it('should serializer query params', () => {
|
||||||
const tree = url.parse("/one?a");
|
const tree = url.parse('/one?a');
|
||||||
expect(url.serialize(tree)).toEqual("/one?a=true");
|
expect(url.serialize(tree)).toEqual('/one?a=true');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse fragment", () => {
|
it('should parse fragment', () => {
|
||||||
const tree = url.parse("/one#two");
|
const tree = url.parse('/one#two');
|
||||||
expect(tree.fragment).toEqual("two");
|
expect(tree.fragment).toEqual('two');
|
||||||
expect(url.serialize(tree)).toEqual("/one#two");
|
expect(url.serialize(tree)).toEqual('/one#two');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse empty fragment", () => {
|
it('should parse empty fragment', () => {
|
||||||
const tree = url.parse("/one#");
|
const tree = url.parse('/one#');
|
||||||
expect(tree.fragment).toEqual("");
|
expect(tree.fragment).toEqual('');
|
||||||
expect(url.serialize(tree)).toEqual("/one#");
|
expect(url.serialize(tree)).toEqual('/one#');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function expectSegment(segment:UrlSegment, expected:string, hasChildren: boolean = false):void {
|
function expectSegment(segment: UrlSegment, expected: string, hasChildren: boolean = false): void {
|
||||||
const p = segment.pathsWithParams.map(p => serializePath(p)).join("/");
|
const p = segment.pathsWithParams.map(p => serializePath(p)).join('/');
|
||||||
expect(p).toEqual(expected);
|
expect(p).toEqual(expected);
|
||||||
expect(Object.keys(segment.children).length > 0).toEqual(hasChildren);
|
expect(Object.keys(segment.children).length > 0).toEqual(hasChildren);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,63 +4,63 @@ import {UrlTree, containsTree} from '../src/url_tree';
|
||||||
describe('UrlTree', () => {
|
describe('UrlTree', () => {
|
||||||
const serializer = new DefaultUrlSerializer();
|
const serializer = new DefaultUrlSerializer();
|
||||||
|
|
||||||
describe("containsTree", () => {
|
describe('containsTree', () => {
|
||||||
describe("exact = true", () => {
|
describe('exact = true', () => {
|
||||||
it("should return true when two tree are the same", () => {
|
it('should return true when two tree are the same', () => {
|
||||||
const url = "/one/(one//left:three)(right:four)";
|
const url = '/one/(one//left:three)(right:four)';
|
||||||
const t1 = serializer.parse(url);
|
const t1 = serializer.parse(url);
|
||||||
const t2 = serializer.parse(url);
|
const t2 = serializer.parse(url);
|
||||||
expect(containsTree(t1, t2, true)).toBe(true);
|
expect(containsTree(t1, t2, true)).toBe(true);
|
||||||
expect(containsTree(t2, t1, true)).toBe(true);
|
expect(containsTree(t2, t1, true)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false when paths are not the same", () => {
|
it('should return false when paths are not the same', () => {
|
||||||
const t1 = serializer.parse("/one/two(right:three)");
|
const t1 = serializer.parse('/one/two(right:three)');
|
||||||
const t2 = serializer.parse("/one/two2(right:three)");
|
const t2 = serializer.parse('/one/two2(right:three)');
|
||||||
expect(containsTree(t1, t2, true)).toBe(false);
|
expect(containsTree(t1, t2, true)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false when container has an extra child", () => {
|
it('should return false when container has an extra child', () => {
|
||||||
const t1 = serializer.parse("/one/two(right:three)");
|
const t1 = serializer.parse('/one/two(right:three)');
|
||||||
const t2 = serializer.parse("/one/two");
|
const t2 = serializer.parse('/one/two');
|
||||||
expect(containsTree(t1, t2, true)).toBe(false);
|
expect(containsTree(t1, t2, true)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false when containee has an extra child", () => {
|
it('should return false when containee has an extra child', () => {
|
||||||
const t1 = serializer.parse("/one/two");
|
const t1 = serializer.parse('/one/two');
|
||||||
const t2 = serializer.parse("/one/two(right:three)");
|
const t2 = serializer.parse('/one/two(right:three)');
|
||||||
expect(containsTree(t1, t2, true)).toBe(false);
|
expect(containsTree(t1, t2, true)).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("exact = false", () => {
|
describe('exact = false', () => {
|
||||||
it("should return true when containee is missing a segment", () => {
|
it('should return true when containee is missing a segment', () => {
|
||||||
const t1 = serializer.parse("/one/(two//left:three)(right:four)");
|
const t1 = serializer.parse('/one/(two//left:three)(right:four)');
|
||||||
const t2 = serializer.parse("/one/(two//left:three)");
|
const t2 = serializer.parse('/one/(two//left:three)');
|
||||||
expect(containsTree(t1, t2, false)).toBe(true);
|
expect(containsTree(t1, t2, false)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return true when containee is missing some paths", () => {
|
it('should return true when containee is missing some paths', () => {
|
||||||
const t1 = serializer.parse("/one/two/three");
|
const t1 = serializer.parse('/one/two/three');
|
||||||
const t2 = serializer.parse("/one/two");
|
const t2 = serializer.parse('/one/two');
|
||||||
expect(containsTree(t1, t2, false)).toBe(true);
|
expect(containsTree(t1, t2, false)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return true container has its paths splitted into multiple segments", () => {
|
it('should return true container has its paths splitted into multiple segments', () => {
|
||||||
const t1 = serializer.parse("/one/(two//left:three)");
|
const t1 = serializer.parse('/one/(two//left:three)');
|
||||||
const t2 = serializer.parse("/one/two");
|
const t2 = serializer.parse('/one/two');
|
||||||
expect(containsTree(t1, t2, false)).toBe(true);
|
expect(containsTree(t1, t2, false)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false when containee has extra segments", () => {
|
it('should return false when containee has extra segments', () => {
|
||||||
const t1 = serializer.parse("/one/two");
|
const t1 = serializer.parse('/one/two');
|
||||||
const t2 = serializer.parse("/one/(two//left:three)");
|
const t2 = serializer.parse('/one/(two//left:three)');
|
||||||
expect(containsTree(t1, t2, false)).toBe(false);
|
expect(containsTree(t1, t2, false)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return containee has segments that the container does not have", () => {
|
it('should return containee has segments that the container does not have', () => {
|
||||||
const t1 = serializer.parse("/one/(two//left:three)");
|
const t1 = serializer.parse('/one/(two//left:three)');
|
||||||
const t2 = serializer.parse("/one/(two//right:four)");
|
const t2 = serializer.parse('/one/(two//right:four)');
|
||||||
expect(containsTree(t1, t2, false)).toBe(false);
|
expect(containsTree(t1, t2, false)).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,50 +1,51 @@
|
||||||
import {Tree, TreeNode} from '../../src/utils/tree';
|
import {Tree, TreeNode} from '../../src/utils/tree';
|
||||||
|
|
||||||
describe('tree', () => {
|
describe('tree', () => {
|
||||||
it("should return the root of the tree", () => {
|
it('should return the root of the tree', () => {
|
||||||
const t = new Tree<any>(new TreeNode<number>(1, []));
|
const t = new Tree<any>(new TreeNode<number>(1, []));
|
||||||
expect(t.root).toEqual(1);
|
expect(t.root).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the parent of a node", () => {
|
it('should return the parent of a node', () => {
|
||||||
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
||||||
expect(t.parent(1)).toEqual(null);
|
expect(t.parent(1)).toEqual(null);
|
||||||
expect(t.parent(2)).toEqual(1);
|
expect(t.parent(2)).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the children of a node", () => {
|
it('should return the children of a node', () => {
|
||||||
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
||||||
expect(t.children(1)).toEqual([2]);
|
expect(t.children(1)).toEqual([2]);
|
||||||
expect(t.children(2)).toEqual([]);
|
expect(t.children(2)).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the first child of a node", () => {
|
it('should return the first child of a node', () => {
|
||||||
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
||||||
expect(t.firstChild(1)).toEqual(2);
|
expect(t.firstChild(1)).toEqual(2);
|
||||||
expect(t.firstChild(2)).toEqual(null);
|
expect(t.firstChild(2)).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the siblings of a node", () => {
|
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, [])]));
|
const t = new Tree<any>(
|
||||||
|
new TreeNode<number>(1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])]));
|
||||||
expect(t.siblings(2)).toEqual([3]);
|
expect(t.siblings(2)).toEqual([3]);
|
||||||
expect(t.siblings(1)).toEqual([]);
|
expect(t.siblings(1)).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the path to the root", () => {
|
it('should return the path to the root', () => {
|
||||||
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
const t = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
||||||
expect(t.pathFromRoot(2)).toEqual([1, 2]);
|
expect(t.pathFromRoot(2)).toEqual([1, 2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("contains", () => {
|
describe('contains', () => {
|
||||||
it("should work", () => {
|
it('should work', () => {
|
||||||
const tree = new Tree<any>(
|
const tree = new Tree<any>(
|
||||||
new TreeNode<number>(1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])]));
|
new TreeNode<number>(1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])]));
|
||||||
const subtree1 = new Tree<any>(new TreeNode<number>(1, []));
|
const subtree1 = new Tree<any>(new TreeNode<number>(1, []));
|
||||||
const subtree2 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
const subtree2 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
||||||
const subtree3 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(3, [])]));
|
const subtree3 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(3, [])]));
|
||||||
const notSubtree1 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(4, [])]));
|
const notSubtree1 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(4, [])]));
|
||||||
const notSubtree2 = new Tree<any>(
|
const notSubtree2 = new Tree<any>(
|
||||||
new TreeNode<number>(1, [new TreeNode<number>(2, [new TreeNode<number>(4, [])])]));
|
new TreeNode<number>(1, [new TreeNode<number>(2, [new TreeNode<number>(4, [])])]));
|
||||||
|
|
||||||
expect(tree.contains(subtree1)).toEqual(true);
|
expect(tree.contains(subtree1)).toEqual(true);
|
||||||
expect(tree.contains(subtree2)).toEqual(true);
|
expect(tree.contains(subtree2)).toEqual(true);
|
||||||
|
|
Loading…
Reference in New Issue