@@ -18,7 +18,7 @@ import {
|
||||
import {Injector, bind} from 'angular2/di';
|
||||
import {Component, View} from 'angular2/src/core/annotations/decorators';
|
||||
import * as annotations from 'angular2/src/core/annotations_impl/view';
|
||||
import {CONST} from 'angular2/src/facade/lang';
|
||||
import {CONST, NumberWrapper} from 'angular2/src/facade/lang';
|
||||
|
||||
import {RootRouter} from 'angular2/src/router/router';
|
||||
import {Pipeline} from 'angular2/src/router/pipeline';
|
||||
@@ -42,7 +42,7 @@ export function main() {
|
||||
|
||||
beforeEachBindings(() => [
|
||||
Pipeline,
|
||||
bind(RouteRegistry).toFactory(() => new RouteRegistry(MyComp)),
|
||||
RouteRegistry,
|
||||
DirectiveResolver,
|
||||
bind(Location).toClass(SpyLocation),
|
||||
bind(Router)
|
||||
@@ -185,6 +185,49 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('should generate link hrefs from a child to its sibling',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile()
|
||||
.then((_) => rtr.config(
|
||||
{'path': '/page/:number', 'component': SiblingPageCmp, 'as': 'page'}))
|
||||
.then((_) => rtr.navigate('/page/1'))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(DOM.getAttribute(rootTC.componentViewChildren[1]
|
||||
.componentViewChildren[0]
|
||||
.children[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/page/2');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate relative links preserving the existing parent route',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile()
|
||||
.then((_) =>
|
||||
rtr.config({'path': '/book/:title/...', 'component': BookCmp, 'as': 'book'}))
|
||||
.then((_) => rtr.navigate('/book/1984/page/1'))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(DOM.getAttribute(
|
||||
rootTC.componentViewChildren[1].componentViewChildren[0].nativeElement,
|
||||
'href'))
|
||||
.toEqual('/book/1984/page/100');
|
||||
|
||||
expect(DOM.getAttribute(rootTC.componentViewChildren[1]
|
||||
.componentViewChildren[2]
|
||||
.componentViewChildren[0]
|
||||
.children[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/book/1984/page/2');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
describe('when clicked', () => {
|
||||
|
||||
var clickOnElement = function(view) {
|
||||
@@ -266,6 +309,34 @@ class UserCmp {
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'page-cmp'})
|
||||
@View({
|
||||
template:
|
||||
`page #{{pageNumber}} | <a href="hello" [router-link]="[\'../page\', {number: nextPage}]">next</a>`,
|
||||
directives: [RouterLink]
|
||||
})
|
||||
class SiblingPageCmp {
|
||||
pageNumber: number;
|
||||
nextPage: number;
|
||||
constructor(params: RouteParams) {
|
||||
this.pageNumber = NumberWrapper.parseInt(params.get('number'), 10);
|
||||
this.nextPage = this.pageNumber + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'book-cmp'})
|
||||
@View({
|
||||
template: `<a href="hello" [router-link]="[\'./page\', {number: 100}]">{{title}}</a> |
|
||||
<router-outlet></router-outlet>`,
|
||||
directives: [RouterLink, RouterOutlet]
|
||||
})
|
||||
@RouteConfig([{path: '/page/:number', component: SiblingPageCmp, 'as': 'page'}])
|
||||
class BookCmp {
|
||||
title: string;
|
||||
constructor(params: RouteParams) { this.title = params.get('title'); }
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'parent-cmp'})
|
||||
@View({template: "inner { <router-outlet></router-outlet> }", directives: [RouterOutlet]})
|
||||
@RouteConfig([{path: '/b', component: HelloCmp}])
|
||||
|
||||
@@ -20,7 +20,7 @@ export function main() {
|
||||
describe('RouteRegistry', () => {
|
||||
var registry, rootHostComponent = new Object();
|
||||
|
||||
beforeEach(() => { registry = new RouteRegistry(rootHostComponent); });
|
||||
beforeEach(() => { registry = new RouteRegistry(); });
|
||||
|
||||
it('should match the full URL', inject([AsyncTestCompleter], (async) => {
|
||||
registry.config(rootHostComponent, {'path': '/', 'component': DummyCompA});
|
||||
@@ -37,9 +37,9 @@ export function main() {
|
||||
registry.config(rootHostComponent,
|
||||
{'path': '/first/...', 'component': DummyParentComp, 'as': 'firstCmp'});
|
||||
|
||||
expect(registry.generate(['./firstCmp/secondCmp'], rootHostComponent))
|
||||
.toEqual('/first/second');
|
||||
expect(registry.generate(['./secondCmp'], DummyParentComp)).toEqual('/second');
|
||||
expect(registry.generate(['firstCmp', 'secondCmp'], rootHostComponent))
|
||||
.toEqual('first/second');
|
||||
expect(registry.generate(['secondCmp'], DummyParentComp)).toEqual('second');
|
||||
});
|
||||
|
||||
it('should generate URLs with params', () => {
|
||||
@@ -47,20 +47,9 @@ export function main() {
|
||||
rootHostComponent,
|
||||
{'path': '/first/:param/...', 'component': DummyParentParamComp, 'as': 'firstCmp'});
|
||||
|
||||
var url = registry.generate(['./firstCmp', {param: 'one'}, 'secondCmp', {param: 'two'}],
|
||||
var url = registry.generate(['firstCmp', {param: 'one'}, 'secondCmp', {param: 'two'}],
|
||||
rootHostComponent);
|
||||
expect(url).toEqual('/first/one/second/two');
|
||||
});
|
||||
|
||||
it('should generate URLs from the root component when the path starts with /', () => {
|
||||
registry.config(rootHostComponent,
|
||||
{'path': '/first/...', 'component': DummyParentComp, 'as': 'firstCmp'});
|
||||
|
||||
expect(registry.generate(['/firstCmp', 'secondCmp'], rootHostComponent))
|
||||
.toEqual('/first/second');
|
||||
expect(registry.generate(['/firstCmp', 'secondCmp'], DummyParentComp))
|
||||
.toEqual('/first/second');
|
||||
expect(registry.generate(['/firstCmp/secondCmp'], DummyParentComp)).toEqual('/first/second');
|
||||
expect(url).toEqual('first/one/second/two');
|
||||
});
|
||||
|
||||
it('should generate URLs of loaded components after they are loaded',
|
||||
@@ -71,30 +60,17 @@ export function main() {
|
||||
'as': 'firstCmp'
|
||||
});
|
||||
|
||||
expect(() => registry.generate(['/firstCmp/secondCmp'], rootHostComponent))
|
||||
expect(() => registry.generate(['firstCmp', 'secondCmp'], rootHostComponent))
|
||||
.toThrowError('Could not find route config for "secondCmp".');
|
||||
|
||||
registry.recognize('/first/second', rootHostComponent)
|
||||
.then((_) => {
|
||||
expect(registry.generate(['/firstCmp/secondCmp'], rootHostComponent))
|
||||
.toEqual('/first/second');
|
||||
expect(registry.generate(['firstCmp', 'secondCmp'], rootHostComponent))
|
||||
.toEqual('first/second');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should throw when linkParams does not start with a "/" or "./"', () => {
|
||||
expect(() => registry.generate(['firstCmp', 'secondCmp'], rootHostComponent))
|
||||
.toThrowError(
|
||||
`Link "${ListWrapper.toJSON(['firstCmp', 'secondCmp'])}" must start with "/" or "./"`);
|
||||
});
|
||||
|
||||
it('should throw when linkParams does not include a route name', () => {
|
||||
expect(() => registry.generate(['./'], rootHostComponent))
|
||||
.toThrowError(`Link "${ListWrapper.toJSON(['./'])}" must include a route name.`);
|
||||
expect(() => registry.generate(['/'], rootHostComponent))
|
||||
.toThrowError(`Link "${ListWrapper.toJSON(['/'])}" must include a route name.`);
|
||||
});
|
||||
|
||||
it('should prefer static segments to dynamic', inject([AsyncTestCompleter], (async) => {
|
||||
registry.config(rootHostComponent, {'path': '/:site', 'component': DummyCompB});
|
||||
registry.config(rootHostComponent, {'path': '/home', 'component': DummyCompA});
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import {IMPLEMENTS} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Router, RootRouter} from 'angular2/src/router/router';
|
||||
import {Pipeline} from 'angular2/src/router/pipeline';
|
||||
import {RouterOutlet} from 'angular2/src/router/router_outlet';
|
||||
@@ -21,6 +22,7 @@ import {SpyLocation} from 'angular2/src/mock/location_mock';
|
||||
import {Location} from 'angular2/src/router/location';
|
||||
|
||||
import {RouteRegistry} from 'angular2/src/router/route_registry';
|
||||
import {RouteConfig} from 'angular2/src/router/route_config_decorator';
|
||||
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
||||
|
||||
import {bind} from 'angular2/di';
|
||||
@@ -31,7 +33,7 @@ export function main() {
|
||||
|
||||
beforeEachBindings(() => [
|
||||
Pipeline,
|
||||
bind(RouteRegistry).toFactory(() => new RouteRegistry(AppCmp)),
|
||||
RouteRegistry,
|
||||
DirectiveResolver,
|
||||
bind(Location).toClass(SpyLocation),
|
||||
bind(Router)
|
||||
@@ -74,6 +76,7 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('should navigate after being configured', inject([AsyncTestCompleter], (async) => {
|
||||
var outlet = makeDummyOutlet();
|
||||
|
||||
@@ -88,6 +91,30 @@ export function main() {
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('should throw when linkParams does not start with a "/" or "./"', () => {
|
||||
expect(() => router.generate(['firstCmp', 'secondCmp']))
|
||||
.toThrowError(
|
||||
`Link "${ListWrapper.toJSON(['firstCmp', 'secondCmp'])}" must start with "/", "./", or "../"`);
|
||||
});
|
||||
|
||||
|
||||
it('should throw when linkParams does not include a route name', () => {
|
||||
expect(() => router.generate(['./']))
|
||||
.toThrowError(`Link "${ListWrapper.toJSON(['./'])}" must include a route name.`);
|
||||
expect(() => router.generate(['/']))
|
||||
.toThrowError(`Link "${ListWrapper.toJSON(['/'])}" must include a route name.`);
|
||||
});
|
||||
|
||||
|
||||
it('should generate URLs from the root component when the path starts with /', () => {
|
||||
router.config({'path': '/first/...', 'component': DummyParentComp, 'as': 'firstCmp'});
|
||||
|
||||
expect(router.generate(['/firstCmp', 'secondCmp'])).toEqual('/first/second');
|
||||
expect(router.generate(['/firstCmp', 'secondCmp'])).toEqual('/first/second');
|
||||
expect(router.generate(['/firstCmp/secondCmp'])).toEqual('/first/second');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,6 +126,10 @@ class DummyOutlet extends SpyObject {
|
||||
|
||||
class DummyComponent {}
|
||||
|
||||
@RouteConfig([{'path': '/second', 'component': DummyComponent, 'as': 'secondCmp'}])
|
||||
class DummyParentComp {
|
||||
}
|
||||
|
||||
function makeDummyOutlet() {
|
||||
var ref = new DummyOutlet();
|
||||
ref.spy('activate').andCallFake((_) => PromiseWrapper.resolve(true));
|
||||
|
||||
Reference in New Issue
Block a user