feat(router): implement RouterLinkActive
This commit is contained in:
@ -658,6 +658,90 @@ describe("Integration", () => {
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
||||
describe("routerActiveLink", () => {
|
||||
it("should set the class when the link is active (exact = true)",
|
||||
fakeAsync(inject([Router, TestComponentBuilder, Location], (router, tcb, location) => {
|
||||
const fixture = tcb.createFakeAsync(RootCmp);
|
||||
advance(fixture);
|
||||
|
||||
router.resetConfig([
|
||||
{ path: 'team/:id', component: TeamCmp, children: [
|
||||
{ path: 'link', component: DummyLinkCmp, children: [
|
||||
{path: 'simple', component: SimpleCmp},
|
||||
{path: '', component: BlankCmp}
|
||||
] }
|
||||
] }
|
||||
]);
|
||||
|
||||
router.navigateByUrl('/team/22/link');
|
||||
advance(fixture);
|
||||
expect(location.path()).toEqual('/team/22/link');
|
||||
|
||||
const native = fixture.debugElement.nativeElement.querySelector("a");
|
||||
expect(native.className).toEqual("active");
|
||||
|
||||
router.navigateByUrl('/team/22/link/simple');
|
||||
advance(fixture);
|
||||
expect(location.path()).toEqual('/team/22/link/simple');
|
||||
expect(native.className).toEqual("");
|
||||
})));
|
||||
|
||||
it("should set the class on a parent element when the link is active (exact = true)",
|
||||
fakeAsync(inject([Router, TestComponentBuilder, Location], (router, tcb, location) => {
|
||||
const fixture = tcb.createFakeAsync(RootCmp);
|
||||
advance(fixture);
|
||||
|
||||
router.resetConfig([
|
||||
{ path: 'team/:id', component: TeamCmp, children: [
|
||||
{ path: 'link', component: DummyLinkWithParentCmp, children: [
|
||||
{path: 'simple', component: SimpleCmp},
|
||||
{path: '', component: BlankCmp}
|
||||
] }
|
||||
] }
|
||||
]);
|
||||
|
||||
router.navigateByUrl('/team/22/link');
|
||||
advance(fixture);
|
||||
expect(location.path()).toEqual('/team/22/link');
|
||||
|
||||
const native = fixture.debugElement.nativeElement.querySelector("link-parent");
|
||||
expect(native.className).toEqual("active");
|
||||
|
||||
router.navigateByUrl('/team/22/link/simple');
|
||||
advance(fixture);
|
||||
expect(location.path()).toEqual('/team/22/link/simple');
|
||||
expect(native.className).toEqual("");
|
||||
})));
|
||||
|
||||
it("should set the class when the link is active (exact = false)",
|
||||
fakeAsync(inject([Router, TestComponentBuilder, Location], (router, tcb, location) => {
|
||||
const fixture = tcb.createFakeAsync(RootCmp);
|
||||
advance(fixture);
|
||||
|
||||
router.resetConfig([
|
||||
{ path: 'team/:id', component: TeamCmp, children: [
|
||||
{ path: 'link', component: DummyLinkCmp, children: [
|
||||
{path: 'simple', component: SimpleCmp},
|
||||
{path: '', component: BlankCmp}
|
||||
] }
|
||||
] }
|
||||
]);
|
||||
|
||||
router.navigateByUrl('/team/22/link;exact=false');
|
||||
advance(fixture);
|
||||
expect(location.path()).toEqual('/team/22/link;exact=false');
|
||||
|
||||
const native = fixture.debugElement.nativeElement.querySelector("a");
|
||||
expect(native.className).toEqual("active");
|
||||
|
||||
router.navigateByUrl('/team/22/link/simple');
|
||||
advance(fixture);
|
||||
expect(location.path()).toEqual('/team/22/link/simple');
|
||||
expect(native.className).toEqual("active");
|
||||
})));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
function expectEvents(events:Event[], pairs: any[]) {
|
||||
@ -681,6 +765,27 @@ class StringLinkCmp {}
|
||||
})
|
||||
class AbsoluteLinkCmp {}
|
||||
|
||||
@Component({
|
||||
selector: 'link-cmp',
|
||||
template: `<router-outlet></router-outlet><a routerLinkActive="active" [routerLinkActiveOptions]="{exact: exact}" [routerLink]="['./']">link</a>`,
|
||||
directives: ROUTER_DIRECTIVES
|
||||
})
|
||||
class DummyLinkCmp {
|
||||
private exact: boolean;
|
||||
constructor(route: ActivatedRoute) {
|
||||
// convert 'false' into false
|
||||
this.exact = (<any>route.snapshot.params).exact !== 'false';
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'link-cmp',
|
||||
template: `<router-outlet></router-outlet><link-parent routerLinkActive="active"><a [routerLink]="['./']">link</a></link-parent>`,
|
||||
directives: ROUTER_DIRECTIVES
|
||||
})
|
||||
class DummyLinkWithParentCmp {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'link-cmp',
|
||||
template: `<a [routerLink]="['../simple']">link</a>`,
|
||||
|
68
modules/@angular/router/test/url_tree.spec.ts
Normal file
68
modules/@angular/router/test/url_tree.spec.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import {DefaultUrlSerializer} from '../src/url_serializer';
|
||||
import {UrlTree, containsTree} from '../src/url_tree';
|
||||
|
||||
describe('UrlTree', () => {
|
||||
const serializer = new DefaultUrlSerializer();
|
||||
|
||||
describe("containsTree", () => {
|
||||
describe("exact = true", () => {
|
||||
it("should return true when two tree are the same", () => {
|
||||
const url = "/one/(one//left:three)(right:four)";
|
||||
const t1 = serializer.parse(url);
|
||||
const t2 = serializer.parse(url);
|
||||
expect(containsTree(t1, t2, true)).toBe(true);
|
||||
expect(containsTree(t2, t1, true)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false when paths are not the same", () => {
|
||||
const t1 = serializer.parse("/one/two(right:three)");
|
||||
const t2 = serializer.parse("/one/two2(right:three)");
|
||||
expect(containsTree(t1, t2, true)).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false when container has an extra child", () => {
|
||||
const t1 = serializer.parse("/one/two(right:three)");
|
||||
const t2 = serializer.parse("/one/two");
|
||||
expect(containsTree(t1, t2, true)).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false when containee has an extra child", () => {
|
||||
const t1 = serializer.parse("/one/two");
|
||||
const t2 = serializer.parse("/one/two(right:three)");
|
||||
expect(containsTree(t1, t2, true)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("exact = false", () => {
|
||||
it("should return true when containee is missing a segment", () => {
|
||||
const t1 = serializer.parse("/one/(two//left:three)(right:four)");
|
||||
const t2 = serializer.parse("/one/(two//left:three)");
|
||||
expect(containsTree(t1, t2, false)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true when containee is missing some paths", () => {
|
||||
const t1 = serializer.parse("/one/two/three");
|
||||
const t2 = serializer.parse("/one/two");
|
||||
expect(containsTree(t1, t2, false)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true container has its paths splitted into multiple segments", () => {
|
||||
const t1 = serializer.parse("/one/(two//left:three)");
|
||||
const t2 = serializer.parse("/one/two");
|
||||
expect(containsTree(t1, t2, false)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false when containee has extra segments", () => {
|
||||
const t1 = serializer.parse("/one/two");
|
||||
const t2 = serializer.parse("/one/(two//left:three)");
|
||||
expect(containsTree(t1, t2, false)).toBe(false);
|
||||
});
|
||||
|
||||
it("should return containee has segments that the container does not have", () => {
|
||||
const t1 = serializer.parse("/one/(two//left:three)");
|
||||
const t2 = serializer.parse("/one/(two//right:four)");
|
||||
expect(containsTree(t1, t2, false)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user