chore: router move-only
This commit is contained in:
@ -0,0 +1,656 @@
|
||||
import {
|
||||
beforeEach,
|
||||
beforeEachProviders,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
} from '@angular/core/testing/testing_internal';
|
||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||
|
||||
import {Location} from '@angular/common';
|
||||
|
||||
import {specs, compile, TEST_ROUTER_PROVIDERS, clickOnElement, getHref} from '../util';
|
||||
|
||||
import {Router, AsyncRoute, Route} from '@angular/router';
|
||||
|
||||
import {
|
||||
HelloCmp,
|
||||
helloCmpLoader,
|
||||
UserCmp,
|
||||
userCmpLoader,
|
||||
TeamCmp,
|
||||
asyncTeamLoader,
|
||||
ParentCmp,
|
||||
parentCmpLoader,
|
||||
asyncParentCmpLoader,
|
||||
asyncDefaultParentCmpLoader,
|
||||
ParentWithDefaultCmp,
|
||||
parentWithDefaultCmpLoader,
|
||||
asyncRouteDataCmp
|
||||
} from './fixture_components';
|
||||
import {By} from '../../../../platform-browser/src/dom/debug/by';
|
||||
|
||||
function getLinkElement(rtc: ComponentFixture<any>) {
|
||||
return rtc.debugElement.query(By.css('a')).nativeElement;
|
||||
}
|
||||
|
||||
function asyncRoutesWithoutChildrenWithRouteData() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should inject route data into the component', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute(
|
||||
{path: '/route-data', loader: asyncRouteDataCmp, data: {isAdmin: true}})
|
||||
]))
|
||||
.then((_) => rtr.navigateByUrl('/route-data'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('true');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should inject empty object if the route has no data property',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/route-data-default', loader: asyncRouteDataCmp})]))
|
||||
.then((_) => rtr.navigateByUrl('/route-data-default'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function asyncRoutesWithoutChildrenWithoutParams() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/test', loader: helloCmpLoader, name: 'Hello'})]))
|
||||
.then((_) => rtr.navigateByUrl('/test'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/test', loader: helloCmpLoader, name: 'Hello'})]))
|
||||
.then((_) => rtr.navigate(['/Hello']))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['Hello']">go to hello</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/test', loader: helloCmpLoader, name: 'Hello'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/test');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['Hello']">go to hello</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/test', loader: helloCmpLoader, name: 'Hello'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('go to hello | ');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('go to hello | hello');
|
||||
expect(location.urlChanges).toEqual(['/test']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function asyncRoutesWithoutChildrenWithParams() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/user/:name', loader: userCmpLoader, name: 'User'})]))
|
||||
.then((_) => rtr.navigateByUrl('/user/igor'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello igor');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/user/:name', component: UserCmp, name: 'User'})]))
|
||||
.then((_) => rtr.navigate(['/User', {name: 'brian'}]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello brian');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['User', {name: 'naomi'}]">greet naomi</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/user/:name', loader: userCmpLoader, name: 'User'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/user/naomi');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['User', {name: 'naomi'}]">greet naomi</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/user/:name', loader: userCmpLoader, name: 'User'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('greet naomi | ');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('greet naomi | hello naomi');
|
||||
expect(location.urlChanges).toEqual(['/user/naomi']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate between components with different parameters',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/user/:name', loader: userCmpLoader, name: 'User'})]))
|
||||
.then((_) => rtr.navigateByUrl('/user/brian'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello brian');
|
||||
})
|
||||
.then((_) => rtr.navigateByUrl('/user/igor'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello igor');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function asyncRoutesWithSyncChildrenWithoutDefaultRoutes() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
|
||||
.then((_) => rtr.navigateByUrl('/a/b'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
|
||||
.then((_) => rtr.navigate(['/Parent', 'Child']))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/a');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new AsyncRoute({path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('nav to child | outer { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('nav to child | outer { inner { hello } }');
|
||||
expect(location.urlChanges).toEqual(['/a/b']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function asyncRoutesWithSyncChildrenWithDefaultRoutes() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => rtr.navigateByUrl('/a'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => rtr.navigate(['/Parent']))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/a');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('link to inner | outer { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('link to inner | outer { inner { hello } }');
|
||||
expect(location.urlChanges).toEqual(['/a/b']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function asyncRoutesWithAsyncChildrenWithoutParamsWithoutDefaultRoutes() {
|
||||
var rootTC;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => rtr.navigateByUrl('/a/b'))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => rtr.navigate(['/Parent', 'Child']))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(getHref(getLinkElement(rootTC))).toEqual('/a');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement).toHaveText('nav to child | outer { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement)
|
||||
.toHaveText('nav to child | outer { inner { hello } }');
|
||||
expect(location.urlChanges).toEqual(['/a/b']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(rootTC));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function asyncRoutesWithAsyncChildrenWithoutParamsWithDefaultRoutes() {
|
||||
var rootTC;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute(
|
||||
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => rtr.navigateByUrl('/a'))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute(
|
||||
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => rtr.navigate(['/Parent']))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute(
|
||||
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(getHref(getLinkElement(rootTC))).toEqual('/a');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {rootTC = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute(
|
||||
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})
|
||||
]))
|
||||
.then((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement).toHaveText('nav to child | outer { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
rootTC.detectChanges();
|
||||
expect(rootTC.debugElement.nativeElement)
|
||||
.toHaveText('nav to child | outer { inner { hello } }');
|
||||
expect(location.urlChanges).toEqual(['/a/b']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(rootTC));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `{ <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})
|
||||
]))
|
||||
.then((_) => rtr.navigateByUrl('/team/angular/user/matias'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('{ team angular | user { hello matias } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `{ <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})
|
||||
]))
|
||||
.then((_) => rtr.navigate(['/Team', {id: 'angular'}, 'User', {name: 'matias'}]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('{ team angular | user { hello matias } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/team/angular');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new AsyncRoute({path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('nav to matias { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('nav to matias { team angular | user { hello matias } }');
|
||||
expect(location.urlChanges).toEqual(['/team/angular/user/matias']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
export function registerSpecs() {
|
||||
specs['asyncRoutesWithoutChildrenWithRouteData'] = asyncRoutesWithoutChildrenWithRouteData;
|
||||
specs['asyncRoutesWithoutChildrenWithoutParams'] = asyncRoutesWithoutChildrenWithoutParams;
|
||||
specs['asyncRoutesWithoutChildrenWithParams'] = asyncRoutesWithoutChildrenWithParams;
|
||||
specs['asyncRoutesWithSyncChildrenWithoutDefaultRoutes'] =
|
||||
asyncRoutesWithSyncChildrenWithoutDefaultRoutes;
|
||||
specs['asyncRoutesWithSyncChildrenWithDefaultRoutes'] =
|
||||
asyncRoutesWithSyncChildrenWithDefaultRoutes;
|
||||
specs['asyncRoutesWithAsyncChildrenWithoutParamsWithoutDefaultRoutes'] =
|
||||
asyncRoutesWithAsyncChildrenWithoutParamsWithoutDefaultRoutes;
|
||||
specs['asyncRoutesWithAsyncChildrenWithoutParamsWithDefaultRoutes'] =
|
||||
asyncRoutesWithAsyncChildrenWithoutParamsWithDefaultRoutes;
|
||||
specs['asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes'] =
|
||||
asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes;
|
||||
}
|
@ -0,0 +1,240 @@
|
||||
import {
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
xdescribe,
|
||||
describe,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
beforeEachProviders,
|
||||
it,
|
||||
xit
|
||||
} from '@angular/core/testing/testing_internal';
|
||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||
|
||||
import {Location} from '@angular/common';
|
||||
import {Component} from '@angular/core';
|
||||
import {Router, ROUTER_DIRECTIVES, Route, AuxRoute, RouteConfig} from '@angular/router';
|
||||
import {specs, compile, clickOnElement, getHref} from '../util';
|
||||
import {BaseException} from '../../../src/facade/exceptions';
|
||||
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||
|
||||
function getLinkElement(rtc: ComponentFixture<any>, linkIndex: number = 0) {
|
||||
return rtc.debugElement.queryAll(By.css('a'))[linkIndex].nativeElement;
|
||||
}
|
||||
|
||||
function auxRoutes() {
|
||||
var tcb: TestComponentBuilder;
|
||||
var fixture: ComponentFixture<any>;
|
||||
var rtr;
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should recognize and navigate from the URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Aux'})
|
||||
]))
|
||||
.then((_) => rtr.navigateByUrl('/(modal)'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('main {} | aux {modal}');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate via the link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Modal'})
|
||||
]))
|
||||
.then((_) => rtr.navigate(['/', ['Modal']]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('main {} | aux {modal}');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/', ['Modal']]">open modal</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Modal'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/(modal)');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/', ['Modal']]">open modal</a> | <a [routerLink]="['/Hello']">hello</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Modal'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('open modal | hello | main {} | aux {}');
|
||||
|
||||
var navCount = 0;
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
navCount += 1;
|
||||
fixture.detectChanges();
|
||||
if (navCount == 1) {
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('open modal | hello | main {} | aux {modal}');
|
||||
expect(location.urlChanges).toEqual(['/(modal)']);
|
||||
expect(getHref(getLinkElement(fixture, 0))).toEqual('/(modal)');
|
||||
expect(getHref(getLinkElement(fixture, 1))).toEqual('/hello(modal)');
|
||||
|
||||
// click on primary route link
|
||||
clickOnElement(getLinkElement(fixture, 1));
|
||||
} else if (navCount == 2) {
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('open modal | hello | main {hello} | aux {modal}');
|
||||
expect(location.urlChanges).toEqual(['/(modal)', '/hello(modal)']);
|
||||
expect(getHref(getLinkElement(fixture, 0))).toEqual('/hello(modal)');
|
||||
expect(getHref(getLinkElement(fixture, 1))).toEqual('/hello(modal)');
|
||||
async.done();
|
||||
} else {
|
||||
throw new BaseException(`Unexpected route change #${navCount}`);
|
||||
}
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function auxRoutesWithAPrimaryRoute() {
|
||||
var tcb: TestComponentBuilder;
|
||||
var fixture: ComponentFixture<any>;
|
||||
var rtr;
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should recognize and navigate from the URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Aux'})
|
||||
]))
|
||||
.then((_) => rtr.navigateByUrl('/hello(modal)'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('main {hello} | aux {modal}');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate via the link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Modal'})
|
||||
]))
|
||||
.then((_) => rtr.navigate(['/Hello', ['Modal']]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('main {hello} | aux {modal}');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/Hello', ['Modal']]">open modal</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Modal'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/hello(modal)');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/Hello', ['Modal']]">open modal</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Modal'})
|
||||
]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('open modal | main {} | aux {}');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('open modal | main {hello} | aux {modal}');
|
||||
expect(location.urlChanges).toEqual(['/hello(modal)']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
export function registerSpecs() {
|
||||
specs['auxRoutes'] = auxRoutes;
|
||||
specs['auxRoutesWithAPrimaryRoute'] = auxRoutesWithAPrimaryRoute;
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'hello-cmp', template: `{{greeting}}`})
|
||||
class HelloCmp {
|
||||
greeting: string;
|
||||
constructor() { this.greeting = 'hello'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'modal-cmp', template: `modal`})
|
||||
class ModalCmp {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'aux-cmp',
|
||||
template: 'main {<router-outlet></router-outlet>} | ' +
|
||||
'aux {<router-outlet name="modal"></router-outlet>}',
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
})
|
||||
@RouteConfig([
|
||||
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
|
||||
new AuxRoute({path: '/modal', component: ModalCmp, name: 'Aux'})
|
||||
])
|
||||
class AuxCmp {
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
import {Component, ComponentRef, ViewContainerRef, ViewChild} from '@angular/core';
|
||||
import {
|
||||
AsyncRoute,
|
||||
Route,
|
||||
Redirect,
|
||||
RouteConfig,
|
||||
RouteParams,
|
||||
RouteData,
|
||||
ROUTER_DIRECTIVES
|
||||
} from '@angular/router';
|
||||
import {PromiseWrapper} from '../../../src/facade/async';
|
||||
import {isPresent} from '../../../src/facade/lang';
|
||||
import {DynamicComponentLoader} from '@angular/core/src/linker/dynamic_component_loader';
|
||||
|
||||
@Component({selector: 'goodbye-cmp', template: `{{farewell}}`})
|
||||
export class GoodbyeCmp {
|
||||
farewell: string;
|
||||
constructor() { this.farewell = 'goodbye'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-cmp', template: `{{greeting}}`})
|
||||
export class HelloCmp {
|
||||
greeting: string;
|
||||
constructor() { this.greeting = 'hello'; }
|
||||
}
|
||||
|
||||
export function helloCmpLoader() {
|
||||
return PromiseWrapper.resolve(HelloCmp);
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'user-cmp', template: `hello {{user}}`})
|
||||
export class UserCmp {
|
||||
user: string;
|
||||
constructor(params: RouteParams) { this.user = params.get('name'); }
|
||||
}
|
||||
|
||||
export function userCmpLoader() {
|
||||
return PromiseWrapper.resolve(UserCmp);
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
template: `inner { <router-outlet></router-outlet> }`,
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
})
|
||||
@RouteConfig([new Route({path: '/b', component: HelloCmp, name: 'Child'})])
|
||||
export class ParentCmp {
|
||||
}
|
||||
|
||||
export function parentCmpLoader() {
|
||||
return PromiseWrapper.resolve(ParentCmp);
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
template: `inner { <router-outlet></router-outlet> }`,
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
})
|
||||
@RouteConfig([new AsyncRoute({path: '/b', loader: helloCmpLoader, name: 'Child'})])
|
||||
export class AsyncParentCmp {
|
||||
}
|
||||
|
||||
export function asyncParentCmpLoader() {
|
||||
return PromiseWrapper.resolve(AsyncParentCmp);
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
template: `inner { <router-outlet></router-outlet> }`,
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
})
|
||||
@RouteConfig(
|
||||
[new AsyncRoute({path: '/b', loader: helloCmpLoader, name: 'Child', useAsDefault: true})])
|
||||
export class AsyncDefaultParentCmp {
|
||||
}
|
||||
|
||||
export function asyncDefaultParentCmpLoader() {
|
||||
return PromiseWrapper.resolve(AsyncDefaultParentCmp);
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
template: `inner { <router-outlet></router-outlet> }`,
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
})
|
||||
@RouteConfig([new Route({path: '/b', component: HelloCmp, name: 'Child', useAsDefault: true})])
|
||||
export class ParentWithDefaultCmp {
|
||||
}
|
||||
|
||||
export function parentWithDefaultCmpLoader() {
|
||||
return PromiseWrapper.resolve(ParentWithDefaultCmp);
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'team-cmp',
|
||||
template: `team {{id}} | user { <router-outlet></router-outlet> }`,
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
})
|
||||
@RouteConfig([new Route({path: '/user/:name', component: UserCmp, name: 'User'})])
|
||||
export class TeamCmp {
|
||||
id: string;
|
||||
constructor(params: RouteParams) { this.id = params.get('id'); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'team-cmp',
|
||||
template: `team {{id}} | user { <router-outlet></router-outlet> }`,
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
})
|
||||
@RouteConfig([new AsyncRoute({path: '/user/:name', loader: userCmpLoader, name: 'User'})])
|
||||
export class AsyncTeamCmp {
|
||||
id: string;
|
||||
constructor(params: RouteParams) { this.id = params.get('id'); }
|
||||
}
|
||||
|
||||
export function asyncTeamLoader() {
|
||||
return PromiseWrapper.resolve(AsyncTeamCmp);
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'data-cmp', template: `{{myData}}`})
|
||||
export class RouteDataCmp {
|
||||
myData: boolean;
|
||||
constructor(data: RouteData) { this.myData = data.get('isAdmin'); }
|
||||
}
|
||||
|
||||
export function asyncRouteDataCmp() {
|
||||
return PromiseWrapper.resolve(RouteDataCmp);
|
||||
}
|
||||
|
||||
@Component({selector: 'redirect-to-parent-cmp', template: 'redirect-to-parent'})
|
||||
@RouteConfig([new Redirect({path: '/child-redirect', redirectTo: ['../HelloSib']})])
|
||||
export class RedirectToParentCmp {
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'dynamic-loader-cmp', template: `{ <div #viewport></div> }`})
|
||||
@RouteConfig([new Route({path: '/', component: HelloCmp})])
|
||||
export class DynamicLoaderCmp {
|
||||
private _componentRef: ComponentRef<any> = null;
|
||||
|
||||
@ViewChild('viewport', {read: ViewContainerRef}) viewport: ViewContainerRef;
|
||||
|
||||
constructor(private _dynamicComponentLoader: DynamicComponentLoader) {}
|
||||
|
||||
onSomeAction(): Promise<any> {
|
||||
if (isPresent(this._componentRef)) {
|
||||
this._componentRef.destroy();
|
||||
this._componentRef = null;
|
||||
}
|
||||
return this._dynamicComponentLoader.loadNextToLocation(DynamicallyLoadedComponent,
|
||||
this.viewport)
|
||||
.then((cmp) => { this._componentRef = cmp; });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'loaded-cmp',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
class DynamicallyLoadedComponent {
|
||||
}
|
@ -0,0 +1,487 @@
|
||||
import {
|
||||
beforeEach,
|
||||
beforeEachProviders,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
} from '@angular/core/testing/testing_internal';
|
||||
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
|
||||
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
|
||||
|
||||
import {specs, compile, TEST_ROUTER_PROVIDERS, clickOnElement, getHref} from '../util';
|
||||
import {Location} from '@angular/common';
|
||||
import {Router, Route} from '@angular/router';
|
||||
import {
|
||||
HelloCmp,
|
||||
UserCmp,
|
||||
TeamCmp,
|
||||
ParentCmp,
|
||||
ParentWithDefaultCmp,
|
||||
DynamicLoaderCmp
|
||||
} from './fixture_components';
|
||||
import {PromiseWrapper} from '../../../src/facade/async';
|
||||
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||
|
||||
|
||||
function getLinkElement(rtc: ComponentFixture<any>) {
|
||||
return rtc.debugElement.query(By.css('a')).nativeElement;
|
||||
}
|
||||
|
||||
function syncRoutesWithoutChildrenWithoutParams() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) =>
|
||||
rtr.config([new Route({path: '/test', component: HelloCmp, name: 'Hello'})]))
|
||||
.then((_) => rtr.navigateByUrl('/test'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) =>
|
||||
rtr.config([new Route({path: '/test', component: HelloCmp, name: 'Hello'})]))
|
||||
.then((_) => rtr.navigate(['/Hello']))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['Hello']">go to hello</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) =>
|
||||
rtr.config([new Route({path: '/test', component: HelloCmp, name: 'Hello'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/test');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['Hello']">go to hello</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) =>
|
||||
rtr.config([new Route({path: '/test', component: HelloCmp, name: 'Hello'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('go to hello | ');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('go to hello | hello');
|
||||
expect(location.urlChanges).toEqual(['/test']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function syncRoutesWithoutChildrenWithParams() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/user/:name', component: UserCmp, name: 'User'})]))
|
||||
.then((_) => rtr.navigateByUrl('/user/igor'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello igor');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/user/:name', component: UserCmp, name: 'User'})]))
|
||||
.then((_) => rtr.navigate(['/User', {name: 'brian'}]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello brian');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['User', {name: 'naomi'}]">greet naomi</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/user/:name', component: UserCmp, name: 'User'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/user/naomi');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['User', {name: 'naomi'}]">greet naomi</a> | <router-outlet></router-outlet>`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/user/:name', component: UserCmp, name: 'User'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('greet naomi | ');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('greet naomi | hello naomi');
|
||||
expect(location.urlChanges).toEqual(['/user/naomi']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate between components with different parameters',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/user/:name', component: UserCmp, name: 'User'})]))
|
||||
.then((_) => rtr.navigateByUrl('/user/brian'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello brian');
|
||||
})
|
||||
.then((_) => rtr.navigateByUrl('/user/igor'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('hello igor');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentCmp, name: 'Parent'})]))
|
||||
.then((_) => rtr.navigateByUrl('/a/b'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentCmp, name: 'Parent'})]))
|
||||
.then((_) => rtr.navigate(['/Parent', 'Child']))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentCmp, name: 'Parent'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/a/b');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentCmp, name: 'Parent'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('nav to child | outer { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('nav to child | outer { inner { hello } }');
|
||||
expect(location.urlChanges).toEqual(['/a/b']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `{ <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
|
||||
.then((_) => rtr.navigateByUrl('/team/angular/user/matias'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('{ team angular | user { hello matias } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `{ <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
|
||||
.then((_) => rtr.navigate(['/Team', {id: 'angular'}, 'User', {name: 'matias'}]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('{ team angular | user { hello matias } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/team/angular/user/matias');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(
|
||||
tcb,
|
||||
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config(
|
||||
[new Route({path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('nav to matias { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('nav to matias { team angular | user { hello matias } }');
|
||||
expect(location.urlChanges).toEqual(['/team/angular/user/matias']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
function syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
it('should navigate by URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then(
|
||||
(_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
|
||||
.then((_) => rtr.navigateByUrl('/a'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate by link DSL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then(
|
||||
(_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
|
||||
.then((_) => rtr.navigate(['/Parent']))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should generate a link URL', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, `<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then(
|
||||
(_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(getLinkElement(fixture))).toEqual('/a');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate from a link click',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, `<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then(
|
||||
(_) => rtr.config(
|
||||
[new Route({path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('link to inner | outer { }');
|
||||
|
||||
rtr.subscribe((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('link to inner | outer { inner { hello } }');
|
||||
expect(location.urlChanges).toEqual(['/a/b']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
clickOnElement(getLinkElement(fixture));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function syncRoutesWithDynamicComponents() {
|
||||
var fixture: ComponentFixture<any>;
|
||||
var tcb: TestComponentBuilder;
|
||||
var rtr: Router;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
|
||||
it('should work',
|
||||
inject([AsyncTestCompleter],
|
||||
(async) => {tcb.createAsync(DynamicLoaderCmp)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([new Route({path: '/', component: HelloCmp})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('{ }');
|
||||
return fixture.componentInstance.onSomeAction();
|
||||
})
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
return rtr.navigateByUrl('/');
|
||||
})
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('{ hello }');
|
||||
|
||||
return fixture.componentInstance.onSomeAction();
|
||||
})
|
||||
.then((_) => {
|
||||
|
||||
// TODO(i): This should be rewritten to use NgZone#onStable or
|
||||
// something
|
||||
// similar basically the assertion needs to run when the world is
|
||||
// stable and we don't know when that is, only zones know.
|
||||
PromiseWrapper.resolve(null).then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('{ hello }');
|
||||
async.done();
|
||||
});
|
||||
})}));
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function registerSpecs() {
|
||||
specs['syncRoutesWithoutChildrenWithoutParams'] = syncRoutesWithoutChildrenWithoutParams;
|
||||
specs['syncRoutesWithoutChildrenWithParams'] = syncRoutesWithoutChildrenWithParams;
|
||||
specs['syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams'] =
|
||||
syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams;
|
||||
specs['syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams'] =
|
||||
syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams;
|
||||
specs['syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams'] =
|
||||
syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams;
|
||||
specs['syncRoutesWithDynamicComponents'] = syncRoutesWithDynamicComponents;
|
||||
}
|
Reference in New Issue
Block a user