fix(router): url serializer should handle segments without primary children

This commit is contained in:
vsavkin 2016-06-19 13:45:40 -07:00
parent f164715678
commit 0c50bc6449
3 changed files with 38 additions and 25 deletions

View File

@ -1,5 +1,5 @@
import {PRIMARY_OUTLET} from './shared';
import {UrlPathWithParams, UrlSegment, UrlTree} from './url_tree';
import {UrlPathWithParams, UrlSegment, UrlTree, mapChildrenIntoArray} from './url_tree';
import {forEach} from './utils/collection';
@ -54,38 +54,22 @@ function serializeSegment(segment: UrlSegment, root: boolean): string {
} else {
return `${primary}`;
}
} else if (segment.children[PRIMARY_OUTLET] && !root) {
const children = [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
forEach(segment.children, (v: UrlSegment, k: string) => {
if (k !== PRIMARY_OUTLET) {
children.push(`${k}:${serializeSegment(v, false)}`);
} else if (segment.hasChildren() && !root) {
const children = mapChildrenIntoArray(segment, (v: UrlSegment, k: string) => {
if (k === PRIMARY_OUTLET) {
return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
} else {
return [`${k}:${serializeSegment(v, false)}`];
}
});
return `${serializePaths(segment)}/(${children.join('//')})`;
} else {
return serializePaths(segment);
}
}
function serializeChildren(segment: UrlSegment) {
if (segment.children[PRIMARY_OUTLET]) {
const primary = serializePaths(segment.children[PRIMARY_OUTLET]);
const secondary: string[] = [];
forEach(segment.children, (v: UrlSegment, k: string) => {
if (k !== PRIMARY_OUTLET) {
secondary.push(`${k}:${serializePaths(v)}${serializeChildren(v)}`);
}
});
const secondaryStr = secondary.length > 0 ? `(${secondary.join('//')})` : '';
const primaryChildren = serializeChildren(segment.children[PRIMARY_OUTLET]);
const primaryChildrenStr: string = primaryChildren ? `/${primaryChildren}` : '';
return `${primary}${secondaryStr}${primaryChildrenStr}`;
} else {
return '';
}
}
export function serializePath(path: UrlPathWithParams): string {
return `${path.path}${serializeParams(path.parameters)}`;
}

View File

@ -74,6 +74,8 @@ export class UrlSegment {
forEach(children, (v: any, k: any) => v.parent = this);
}
hasChildren(): boolean { return Object.keys(this.children).length > 0; }
toString(): string { return serializePaths(this); }
}

View File

@ -28,6 +28,33 @@ describe('url serializer', () => {
expect(url.serialize(tree)).toEqual("/one/two(left:three//right:four)");
});
it("should parse segments with empty paths", () => {
const tree = url.parse("/one/two/(;a=1//right:;b=2)");
const c = tree.root.children[PRIMARY_OUTLET];
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].parameters).toEqual({a: '1'});
expect(c.children['right'].pathsWithParams[0].path).toEqual('');
expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'});
expect(url.serialize(tree)).toEqual("/one/two/(;a=1//right:;b=2)");
});
it("should parse segments with empty paths (only aux)", () => {
const tree = url.parse("/one/two/(right:;b=2)");
const c = tree.root.children[PRIMARY_OUTLET];
expectSegment(tree.root.children[PRIMARY_OUTLET], "one/two", true);
expect(c.children['right'].pathsWithParams[0].path).toEqual('');
expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'});
expect(url.serialize(tree)).toEqual("/one/two/(right:;b=2)");
});
it("should parse scoped secondary segments", () => {
const tree = url.parse("/one/(two//left:three)");