feat(router): add initial implementation
This commit is contained in:
156
modules/angular2/test/router/outlet_spec.js
vendored
Normal file
156
modules/angular2/test/router/outlet_spec.js
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
xdescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
beforeEachBindings,
|
||||
it,
|
||||
xit
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {TestBed} from 'angular2/test';
|
||||
|
||||
import {Injector, bind} from 'angular2/di';
|
||||
import {Component, Viewport} from 'angular2/annotations';
|
||||
import {View} from 'angular2/src/core/annotations/view';
|
||||
|
||||
import {RootRouter} from 'angular2/src/router/router';
|
||||
import {Pipeline} from 'angular2/src/router/pipeline';
|
||||
import {Router, RouterOutlet, RouterLink, RouteConfig, RouteParams} from 'angular2/router';
|
||||
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
export function main() {
|
||||
describe('Outlet Directive', () => {
|
||||
|
||||
var ctx, tb, view, router;
|
||||
|
||||
beforeEach(inject([TestBed], (testBed) => {
|
||||
tb = testBed;
|
||||
ctx = new MyComp();
|
||||
}));
|
||||
|
||||
beforeEachBindings(() => {
|
||||
router = new RootRouter(new Pipeline());
|
||||
return [
|
||||
bind(Router).toValue(router)
|
||||
];
|
||||
});
|
||||
|
||||
function compile(template:string = "<router-outlet></router-outlet>") {
|
||||
tb.overrideView(MyComp, new View({template: ('<div>' + template + '</div>'), directives: [RouterOutlet, RouterLink]}));
|
||||
return tb.createView(MyComp, {context: ctx}).then((v) => {
|
||||
view = v;
|
||||
});
|
||||
}
|
||||
|
||||
it('should work in a simple case', inject([AsyncTestCompleter], (async) => {
|
||||
compile()
|
||||
.then((_) => router.config('/test', HelloCmp))
|
||||
.then((_) => router.navigate('/test'))
|
||||
.then((_) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('hello');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('should navigate between components with different parameters', inject([AsyncTestCompleter], (async) => {
|
||||
compile()
|
||||
.then((_) => router.config('/user/:name', UserCmp))
|
||||
.then((_) => router.navigate('/user/brian'))
|
||||
.then((_) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('hello brian');
|
||||
})
|
||||
.then((_) => router.navigate('/user/igor'))
|
||||
.then((_) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('hello igor');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('should work with child routers', inject([AsyncTestCompleter], (async) => {
|
||||
compile('outer { <router-outlet></router-outlet> }')
|
||||
.then((_) => router.config('/a', ParentCmp))
|
||||
.then((_) => router.navigate('/a/b'))
|
||||
.then((_) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('should generate link hrefs', inject([AsyncTestCompleter], (async) => {
|
||||
ctx.name = 'brian';
|
||||
compile('<a href="hello" router-link="user" [router-params]="{name: name}">{{name}}</a>')
|
||||
.then((_) => router.config('/user/:name', UserCmp, 'user'))
|
||||
.then((_) => router.navigate('/a/b'))
|
||||
.then((_) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('brian');
|
||||
expect(DOM.getAttribute(view.rootNodes[0].childNodes[0], 'href')).toEqual('/user/brian');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'hello-cmp'
|
||||
})
|
||||
@View({
|
||||
template: "{{greeting}}"
|
||||
})
|
||||
class HelloCmp {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
this.greeting = "hello";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'user-cmp'
|
||||
})
|
||||
@View({
|
||||
template: "hello {{user}}"
|
||||
})
|
||||
class UserCmp {
|
||||
user:string;
|
||||
constructor(params:RouteParams) {
|
||||
this.user = params.get('name');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'parent-cmp'
|
||||
})
|
||||
@View({
|
||||
template: "inner { <router-outlet></router-outlet> }",
|
||||
directives: [RouterOutlet]
|
||||
})
|
||||
@RouteConfig({
|
||||
path: '/b',
|
||||
component: HelloCmp
|
||||
})
|
||||
class ParentCmp {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
@Component()
|
||||
class MyComp {
|
||||
name;
|
||||
}
|
61
modules/angular2/test/router/route_recognizer_spec.js
vendored
Normal file
61
modules/angular2/test/router/route_recognizer_spec.js
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
describe,
|
||||
it, iit,
|
||||
ddescribe, expect,
|
||||
inject, beforeEach,
|
||||
SpyObject} from 'angular2/test_lib';
|
||||
|
||||
import {RouteRecognizer} from 'angular2/src/router/route_recognizer';
|
||||
|
||||
export function main() {
|
||||
describe('RouteRecognizer', () => {
|
||||
var recognizer;
|
||||
var handler = {
|
||||
'components': { 'a': 'b' }
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
recognizer = new RouteRecognizer();
|
||||
});
|
||||
|
||||
it('should work with a static segment', () => {
|
||||
recognizer.addConfig('/test', handler);
|
||||
|
||||
expect(recognizer.recognize('/test')[0]).toEqual({
|
||||
'handler': { 'components': { 'a': 'b' } },
|
||||
'params': {},
|
||||
'matchedUrl': '/test',
|
||||
'unmatchedUrl': ''
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with a dynamic segment', () => {
|
||||
recognizer.addConfig('/user/:name', handler);
|
||||
expect(recognizer.recognize('/user/brian')[0]).toEqual({
|
||||
'handler': handler,
|
||||
'params': { 'name': 'brian' },
|
||||
'matchedUrl': '/user/brian',
|
||||
'unmatchedUrl': ''
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow redirects', () => {
|
||||
recognizer.addRedirect('/a', '/b');
|
||||
recognizer.addConfig('/b', handler);
|
||||
var solutions = recognizer.recognize('/a');
|
||||
expect(solutions.length).toBe(1);
|
||||
expect(solutions[0]).toEqual({
|
||||
'handler': handler,
|
||||
'params': {},
|
||||
'matchedUrl': '/b',
|
||||
'unmatchedUrl': ''
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate URLs', () => {
|
||||
recognizer.addConfig('/app/user/:name', handler, 'user');
|
||||
expect(recognizer.generate('user', {'name' : 'misko'})).toEqual('/app/user/misko');
|
||||
});
|
||||
});
|
||||
}
|
41
modules/angular2/test/router/route_registry_spec.js
vendored
Normal file
41
modules/angular2/test/router/route_registry_spec.js
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
describe,
|
||||
it, iit,
|
||||
ddescribe, expect,
|
||||
inject, beforeEach,
|
||||
SpyObject} from 'angular2/test_lib';
|
||||
|
||||
import {RouteRegistry} from 'angular2/src/router/route_registry';
|
||||
|
||||
export function main() {
|
||||
describe('RouteRegistry', () => {
|
||||
var registry;
|
||||
var handler = {};
|
||||
var handler2 = {};
|
||||
|
||||
beforeEach(() => {
|
||||
registry = new RouteRegistry();
|
||||
});
|
||||
|
||||
it('should match the full URL', () => {
|
||||
registry.config('/', '/', handler);
|
||||
registry.config('/', '/test', handler2);
|
||||
|
||||
var instruction = registry.recognize('/test');
|
||||
|
||||
expect(instruction.getChildInstruction('default').component).toBe(handler2);
|
||||
});
|
||||
|
||||
it('should match the full URL recursively', () => {
|
||||
registry.config('/', '/first', handler);
|
||||
registry.config(handler, '/second', handler2);
|
||||
|
||||
var instruction = registry.recognize('/first/second');
|
||||
|
||||
expect(instruction.getChildInstruction('default').component).toBe(handler);
|
||||
expect(instruction.getChildInstruction('default').getChildInstruction('default').component).toBe(handler2);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
53
modules/angular2/test/router/router_spec.js
vendored
Normal file
53
modules/angular2/test/router/router_spec.js
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
describe,
|
||||
proxy,
|
||||
it, iit,
|
||||
ddescribe, expect,
|
||||
inject, beforeEach,
|
||||
SpyObject} from 'angular2/test_lib';
|
||||
import {IMPLEMENTS} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {RootRouter, Viewport} from 'angular2/src/router/router';
|
||||
import {Pipeline} from 'angular2/src/router/pipeline';
|
||||
import {RouterOutlet} from 'angular2/src/router/router_outlet';
|
||||
|
||||
|
||||
export function main() {
|
||||
describe('Router', () => {
|
||||
var router;
|
||||
|
||||
beforeEach(() => {
|
||||
router = new RootRouter(new Pipeline());
|
||||
});
|
||||
|
||||
it('should navigate after being configured', inject([AsyncTestCompleter], (async) => {
|
||||
var outlet = makeDummyRef();
|
||||
|
||||
router.registerOutlet(outlet)
|
||||
.then((_) => router.navigate('/a'))
|
||||
.then((_) => {
|
||||
expect(outlet.spy('activate')).not.toHaveBeenCalled();
|
||||
return router.config('/a', {'component': 'A' });
|
||||
})
|
||||
.then((_) => {
|
||||
expect(outlet.spy('activate')).toHaveBeenCalled();
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(RouterOutlet)
|
||||
class DummyOutletRef extends SpyObject {noSuchMethod(m){return super.noSuchMethod(m)}}
|
||||
|
||||
function makeDummyRef() {
|
||||
var ref = new DummyOutletRef();
|
||||
ref.spy('activate').andCallFake((_) => PromiseWrapper.resolve(true));
|
||||
ref.spy('canActivate').andCallFake((_) => PromiseWrapper.resolve(true));
|
||||
ref.spy('canDeactivate').andCallFake((_) => PromiseWrapper.resolve(true));
|
||||
ref.spy('deactivate').andCallFake((_) => PromiseWrapper.resolve(true));
|
||||
return ref;
|
||||
}
|
Reference in New Issue
Block a user