180 lines
6.4 KiB
TypeScript
180 lines
6.4 KiB
TypeScript
|
import {DefaultUrlSerializer} from '../src/url_serializer';
|
||
|
import {UrlTree, UrlSegment} from '../src/url_tree';
|
||
|
import {ActivatedRoute} from '../src/router_state';
|
||
|
import {PRIMARY_OUTLET, Params} from '../src/shared';
|
||
|
import {createUrlTree} from '../src/create_url_tree';
|
||
|
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
||
|
|
||
|
describe('createUrlTree', () => {
|
||
|
const serializer = new DefaultUrlSerializer();
|
||
|
|
||
|
it("should navigate to the root", () => {
|
||
|
const p = serializer.parse("/");
|
||
|
const t = create(p.root, p, ["/"]);
|
||
|
expect(serializer.serialize(t)).toEqual("");
|
||
|
});
|
||
|
|
||
|
it("should support nested segments", () => {
|
||
|
const p = serializer.parse("/a/b");
|
||
|
const t = create(p.root, p, ["/one", 11, "two", 22]);
|
||
|
expect(serializer.serialize(t)).toEqual("/one/11/two/22");
|
||
|
});
|
||
|
|
||
|
it("should preserve secondary segments", () => {
|
||
|
const p = serializer.parse("/a/11/b(right:c)");
|
||
|
const t = create(p.root, p, ["/a", 11, 'd']);
|
||
|
expect(serializer.serialize(t)).toEqual("/a/11/d(right:c)");
|
||
|
});
|
||
|
|
||
|
it('should update matrix parameters', () => {
|
||
|
const p = serializer.parse("/a;aa=11");
|
||
|
const t = create(p.root, p, ["/a", {aa: 22, bb: 33}]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a;aa=22;bb=33");
|
||
|
});
|
||
|
|
||
|
it('should create matrix parameters', () => {
|
||
|
const p = serializer.parse("/a");
|
||
|
const t = create(p.root, p, ["/a", {aa: 22, bb: 33}]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a;aa=22;bb=33");
|
||
|
});
|
||
|
|
||
|
it('should create matrix parameters together with other segments', () => {
|
||
|
const p = serializer.parse("/a");
|
||
|
const t = create(p.root, p, ["/a", "/b", {aa: 22, bb: 33}]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a/b;aa=22;bb=33");
|
||
|
});
|
||
|
|
||
|
describe("node reuse", () => {
|
||
|
it('should reuse nodes when path is the same', () => {
|
||
|
const p = serializer.parse("/a/b");
|
||
|
const t = create(p.root, p, ['/a/c']);
|
||
|
|
||
|
expect(t.root).toBe(p.root);
|
||
|
expect(t.firstChild(t.root)).toBe(p.firstChild(p.root));
|
||
|
expect(t.firstChild(<any>t.firstChild(t.root))).not.toBe(p.firstChild(<any>p.firstChild(p.root)));
|
||
|
});
|
||
|
|
||
|
it("should create new node when params are the same", () => {
|
||
|
const p = serializer.parse("/a;x=1");
|
||
|
const t = create(p.root, p, ['/a', {'x': 1}]);
|
||
|
|
||
|
expect(t.firstChild(t.root)).toBe(p.firstChild(p.root));
|
||
|
});
|
||
|
|
||
|
it("should create new node when params are different", () => {
|
||
|
const p = serializer.parse("/a;x=1");
|
||
|
const t = create(p.root, p, ['/a', {'x': 2}]);
|
||
|
|
||
|
expect(t.firstChild(t.root)).not.toBe(p.firstChild(p.root));
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("relative navigation", () => {
|
||
|
it("should work", () => {
|
||
|
const p = serializer.parse("/a(left:ap)/c(left:cp)");
|
||
|
const c = p.firstChild(p.root);
|
||
|
const t = create(c, p, ["c2"]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a(left:ap)/c2(left:cp)");
|
||
|
});
|
||
|
|
||
|
it("should work when the first command starts with a ./", () => {
|
||
|
const p = serializer.parse("/a(left:ap)/c(left:cp)");
|
||
|
const c = p.firstChild(p.root);
|
||
|
const t = create(c, p, ["./c2"]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a(left:ap)/c2(left:cp)");
|
||
|
});
|
||
|
|
||
|
it("should work when the first command is ./)", () => {
|
||
|
const p = serializer.parse("/a(left:ap)/c(left:cp)");
|
||
|
const c = p.firstChild(p.root);
|
||
|
const t = create(c, p, ["./", "c2"]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a(left:ap)/c2(left:cp)");
|
||
|
});
|
||
|
|
||
|
it("should work when given params", () => {
|
||
|
const p = serializer.parse("/a(left:ap)/c(left:cp)");
|
||
|
const c = p.firstChild(p.root);
|
||
|
const t = create(c, p, [{'x': 99}]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a(left:ap)/c;x=99(left:cp)");
|
||
|
});
|
||
|
|
||
|
it("should support going to a parent", () => {
|
||
|
const p = serializer.parse("/a(left:ap)/c(left:cp)");
|
||
|
const c = p.firstChild(p.root);
|
||
|
const t = create(c, p, ["../a2"]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a2(left:ap)");
|
||
|
});
|
||
|
|
||
|
it("should support going to a parent (nested case)", () => {
|
||
|
const p = serializer.parse("/a/c");
|
||
|
const c = p.firstChild(<any>p.firstChild(p.root));
|
||
|
const t = create(c, p, ["../c2"]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a/c2");
|
||
|
});
|
||
|
|
||
|
it("should work when given ../", () => {
|
||
|
const p = serializer.parse("/a/c");
|
||
|
const c = p.firstChild(<any>p.firstChild(p.root));
|
||
|
const t = create(c, p, ["../"]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a");
|
||
|
});
|
||
|
|
||
|
it("should navigate to the root", () => {
|
||
|
const p = serializer.parse("/a/c");
|
||
|
const c = p.firstChild(p.root);
|
||
|
const t = create(c, p, ["../"]);
|
||
|
expect(serializer.serialize(t)).toEqual("");
|
||
|
});
|
||
|
|
||
|
it("should support setting matrix params", () => {
|
||
|
const p = serializer.parse("/a(left:ap)/c(left:cp)");
|
||
|
const c = p.firstChild(p.root);
|
||
|
const t = create(c, p, ["../", {'x': 5}]);
|
||
|
expect(serializer.serialize(t)).toEqual("/a;x=5(left:ap)");
|
||
|
});
|
||
|
|
||
|
it("should throw when too many ..", () => {
|
||
|
const p = serializer.parse("/a(left:ap)/c(left:cp)");
|
||
|
const c = p.firstChild(p.root);
|
||
|
expect(() => create(c, p, ["../../"])).toThrowError("Invalid number of '../'");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it("should set query params", () => {
|
||
|
const p = serializer.parse("/");
|
||
|
const t = create(p.root, p, [], {a: 'hey'});
|
||
|
expect(t.queryParameters).toEqual({a: 'hey'});
|
||
|
});
|
||
|
|
||
|
it("should stringify query params", () => {
|
||
|
const p = serializer.parse("/");
|
||
|
const t = create(p.root, p, [], <any>{a: 1});
|
||
|
expect(t.queryParameters).toEqual({a: '1'});
|
||
|
});
|
||
|
|
||
|
it("should reuse old query params when given undefined", () => {
|
||
|
const p = serializer.parse("/?a=1");
|
||
|
const t = create(p.root, p, [], undefined);
|
||
|
expect(t.queryParameters).toEqual({a: '1'});
|
||
|
});
|
||
|
|
||
|
it("should set fragment", () => {
|
||
|
const p = serializer.parse("/");
|
||
|
const t = create(p.root, p, [], {}, "fragment");
|
||
|
expect(t.fragment).toEqual("fragment");
|
||
|
});
|
||
|
|
||
|
it("should reused old fragment when given undefined", () => {
|
||
|
const p = serializer.parse("/#fragment");
|
||
|
const t = create(p.root, p, [], undefined, undefined);
|
||
|
expect(t.fragment).toEqual("fragment");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function create(start: UrlSegment | null, tree: UrlTree, commands: any[], queryParameters?: Params, fragment?: string) {
|
||
|
if (!start) {
|
||
|
expect(start).toBeDefined();
|
||
|
}
|
||
|
const a = new ActivatedRoute(new BehaviorSubject([start]), <any>null, PRIMARY_OUTLET, "someComponent");
|
||
|
return createUrlTree(a, tree, commands, queryParameters, fragment);
|
||
|
}
|