feat(router): add RouterTestModule
This commit is contained in:
parent
c43dd5a655
commit
72544ba551
|
@ -25,21 +25,7 @@ import {DefaultUrlSerializer, UrlSerializer} from './url_tree';
|
||||||
*/
|
*/
|
||||||
export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive];
|
export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive];
|
||||||
|
|
||||||
|
export const ROUTER_PROVIDERS: any[] = [
|
||||||
/**
|
|
||||||
* Router module.
|
|
||||||
*
|
|
||||||
* ### Example
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* bootstrap(AppCmp, {modules: [RouterModule]});
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
@AppModule({
|
|
||||||
directives: ROUTER_DIRECTIVES,
|
|
||||||
providers: [
|
|
||||||
Location, {provide: LocationStrategy, useClass: PathLocationStrategy},
|
Location, {provide: LocationStrategy, useClass: PathLocationStrategy},
|
||||||
{provide: UrlSerializer, useClass: DefaultUrlSerializer}, {
|
{provide: UrlSerializer, useClass: DefaultUrlSerializer}, {
|
||||||
provide: Router,
|
provide: Router,
|
||||||
|
@ -53,8 +39,20 @@ export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref,
|
||||||
{provide: ActivatedRoute, useFactory: (r: Router) => r.routerState.root, deps: [Router]},
|
{provide: ActivatedRoute, useFactory: (r: Router) => r.routerState.root, deps: [Router]},
|
||||||
{provide: AppModuleFactoryLoader, useClass: SystemJsAppModuleLoader},
|
{provide: AppModuleFactoryLoader, useClass: SystemJsAppModuleLoader},
|
||||||
{provide: ROUTER_CONFIGURATION, useValue: {enableTracing: false}}
|
{provide: ROUTER_CONFIGURATION, useValue: {enableTracing: false}}
|
||||||
]
|
];
|
||||||
})
|
|
||||||
|
/**
|
||||||
|
* Router module.
|
||||||
|
*
|
||||||
|
* ### Example
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* bootstrap(AppCmp, {modules: [RouterModule]});
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
@AppModule({directives: ROUTER_DIRECTIVES, providers: ROUTER_PROVIDERS})
|
||||||
export class RouterModule {
|
export class RouterModule {
|
||||||
constructor(private injector: Injector) {
|
constructor(private injector: Injector) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -1,44 +1,21 @@
|
||||||
import 'rxjs/add/operator/map';
|
import 'rxjs/add/operator/map';
|
||||||
|
import {Location} from '@angular/common';
|
||||||
import {Location, LocationStrategy} from '@angular/common';
|
|
||||||
import {SpyLocation} from '@angular/common/testing';
|
|
||||||
import {MockLocationStrategy} from '@angular/common/testing/mock_location_strategy';
|
|
||||||
import {ComponentFixture, TestComponentBuilder} from '@angular/compiler/testing';
|
import {ComponentFixture, TestComponentBuilder} from '@angular/compiler/testing';
|
||||||
import {AppModule, AppModuleFactory, AppModuleFactoryLoader, Compiler, Component, Injectable, Injector, Type} from '@angular/core';
|
import {AppModule, AppModuleFactory, AppModuleFactoryLoader, Compiler, Component, Injectable} from '@angular/core';
|
||||||
import {ComponentResolver} from '@angular/core';
|
import {beforeEach, beforeEachProviders, configureModule, describe, fakeAsync, inject, it, tick} from '@angular/core/testing';
|
||||||
import {beforeEach, beforeEachProviders, ddescribe, describe, fakeAsync, iit, inject, it, tick, xdescribe, xit} from '@angular/core/testing';
|
|
||||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import {of } from 'rxjs/observable/of';
|
import {of } from 'rxjs/observable/of';
|
||||||
|
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Params, ROUTER_DIRECTIVES, Resolve, Router, RouterStateSnapshot, RoutesRecognized, provideRoutes} from '../index';
|
||||||
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, DefaultUrlSerializer, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Params, ROUTER_DIRECTIVES, Resolve, Router, RouterOutletMap, RouterStateSnapshot, Routes, RoutesRecognized, UrlSerializer, provideRoutes} from '../index';
|
import {RouterTestModule, SpyAppModuleFactoryLoader} from '../testing';
|
||||||
|
|
||||||
describe('Integration', () => {
|
describe('Integration', () => {
|
||||||
|
beforeEach(() => {
|
||||||
beforeEachProviders(() => {
|
configureModule({
|
||||||
let config: Routes = [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}];
|
modules: [RouterTestModule],
|
||||||
|
providers: [provideRoutes(
|
||||||
return [
|
[{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}])]
|
||||||
RouterOutletMap,
|
});
|
||||||
{provide: UrlSerializer, useClass: DefaultUrlSerializer},
|
|
||||||
{provide: Location, useClass: SpyLocation},
|
|
||||||
{provide: LocationStrategy, useClass: MockLocationStrategy},
|
|
||||||
{
|
|
||||||
provide: Router,
|
|
||||||
useFactory:
|
|
||||||
(resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap,
|
|
||||||
location: Location, loader: AppModuleFactoryLoader, injector: Injector) => {
|
|
||||||
return new Router(
|
|
||||||
RootCmp, resolver, urlSerializer, outletMap, location, injector, loader, config);
|
|
||||||
},
|
|
||||||
deps: [
|
|
||||||
ComponentResolver, UrlSerializer, RouterOutletMap, Location, AppModuleFactoryLoader,
|
|
||||||
Injector
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{provide: AppModuleFactoryLoader, useClass: SpyAppModuleFactoryLoader},
|
|
||||||
{provide: ActivatedRoute, useFactory: (r: Router) => r.routerState.root, deps: [Router]},
|
|
||||||
];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should navigate with a provided config',
|
it('should navigate with a provided config',
|
||||||
|
@ -1095,7 +1072,7 @@ describe('Integration', () => {
|
||||||
it('works', fakeAsync(inject(
|
it('works', fakeAsync(inject(
|
||||||
[Router, TestComponentBuilder, Location, AppModuleFactoryLoader],
|
[Router, TestComponentBuilder, Location, AppModuleFactoryLoader],
|
||||||
(router: Router, tcb: TestComponentBuilder, location: Location,
|
(router: Router, tcb: TestComponentBuilder, location: Location,
|
||||||
loader: AppModuleFactoryLoader) => {
|
loader: SpyAppModuleFactoryLoader) => {
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'lazy',
|
selector: 'lazy',
|
||||||
template: 'lazy-loaded-parent {<router-outlet></router-outlet>}',
|
template: 'lazy-loaded-parent {<router-outlet></router-outlet>}',
|
||||||
|
@ -1118,8 +1095,9 @@ describe('Integration', () => {
|
||||||
})
|
})
|
||||||
class LoadedModule {
|
class LoadedModule {
|
||||||
}
|
}
|
||||||
(<any>loader).expectedPath = 'expected';
|
|
||||||
(<any>loader).expected = LoadedModule;
|
|
||||||
|
loader.stubbedModules = {expected: LoadedModule};
|
||||||
|
|
||||||
const fixture = createRoot(tcb, router, RootCmp);
|
const fixture = createRoot(tcb, router, RootCmp);
|
||||||
|
|
||||||
|
@ -1137,8 +1115,8 @@ describe('Integration', () => {
|
||||||
fakeAsync(inject(
|
fakeAsync(inject(
|
||||||
[Router, TestComponentBuilder, Location, AppModuleFactoryLoader],
|
[Router, TestComponentBuilder, Location, AppModuleFactoryLoader],
|
||||||
(router: Router, tcb: TestComponentBuilder, location: Location,
|
(router: Router, tcb: TestComponentBuilder, location: Location,
|
||||||
loader: AppModuleFactoryLoader) => {
|
loader: SpyAppModuleFactoryLoader) => {
|
||||||
(<any>loader).expectedPath = 'expected';
|
loader.stubbedModules = {};
|
||||||
const fixture = createRoot(tcb, router, RootCmp);
|
const fixture = createRoot(tcb, router, RootCmp);
|
||||||
|
|
||||||
router.resetConfig([{path: 'lazy', loadChildren: 'invalid'}]);
|
router.resetConfig([{path: 'lazy', loadChildren: 'invalid'}]);
|
||||||
|
@ -1158,22 +1136,6 @@ describe('Integration', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class SpyAppModuleFactoryLoader implements AppModuleFactoryLoader {
|
|
||||||
public expected: any;
|
|
||||||
public expectedPath: string;
|
|
||||||
|
|
||||||
constructor(private compiler: Compiler) {}
|
|
||||||
|
|
||||||
load(path: string): Promise<AppModuleFactory<any>> {
|
|
||||||
if (path === this.expectedPath) {
|
|
||||||
return this.compiler.compileAppModuleAsync(this.expected);
|
|
||||||
} else {
|
|
||||||
return <any>Promise.reject(new Error('boom'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function expectEvents(events: Event[], pairs: any[]) {
|
function expectEvents(events: Event[], pairs: any[]) {
|
||||||
for (let i = 0; i < events.length; ++i) {
|
for (let i = 0; i < events.length; ++i) {
|
||||||
expect((<any>events[i].constructor).name).toBe(pairs[i][0].name);
|
expect((<any>events[i].constructor).name).toBe(pairs[i][0].name);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './testing/router_test_module';
|
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Location, LocationStrategy} from '@angular/common';
|
||||||
|
import {SpyLocation} from '@angular/common/testing';
|
||||||
|
import {MockLocationStrategy} from '@angular/common/testing/mock_location_strategy';
|
||||||
|
import {AppModule, AppModuleFactory, AppModuleFactoryLoader, Compiler, ComponentResolver, Injectable, Injector} from '@angular/core';
|
||||||
|
|
||||||
|
import {Router, RouterOutletMap, Routes, UrlSerializer} from '../index';
|
||||||
|
import {ROUTES} from '../src/router_config_loader';
|
||||||
|
import {ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from '../src/router_module';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A spy for {@link AppModuleFactoryLoader} that allows tests to simulate the loading of app module
|
||||||
|
* factories.
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class SpyAppModuleFactoryLoader implements AppModuleFactoryLoader {
|
||||||
|
public stubbedModules: {[path: string]: any} = {};
|
||||||
|
|
||||||
|
constructor(private compiler: Compiler) {}
|
||||||
|
|
||||||
|
load(path: string): Promise<AppModuleFactory<any>> {
|
||||||
|
if (this.stubbedModules[path]) {
|
||||||
|
return this.compiler.compileAppModuleAsync(this.stubbedModules[path]);
|
||||||
|
} else {
|
||||||
|
return <any>Promise.reject(new Error(`Cannot find module ${path}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A module setting up the router that should be used for testing.
|
||||||
|
* It provides spy implementations of Location, LocationStrategy, and AppModuleFactoryLoader.
|
||||||
|
*
|
||||||
|
* # Example:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* beforeEach(() => {
|
||||||
|
* configureModule({
|
||||||
|
* modules: [RouterTestModule],
|
||||||
|
* providers: [provideRoutes(
|
||||||
|
* [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}])]
|
||||||
|
* });
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
@AppModule({
|
||||||
|
directives: ROUTER_DIRECTIVES,
|
||||||
|
providers: [
|
||||||
|
ROUTER_PROVIDERS,
|
||||||
|
{provide: Location, useClass: SpyLocation},
|
||||||
|
{provide: LocationStrategy, useClass: MockLocationStrategy},
|
||||||
|
{provide: AppModuleFactoryLoader, useClass: SpyAppModuleFactoryLoader},
|
||||||
|
{
|
||||||
|
provide: Router,
|
||||||
|
useFactory: (resolver: ComponentResolver, urlSerializer: UrlSerializer,
|
||||||
|
outletMap: RouterOutletMap, location: Location, loader: AppModuleFactoryLoader,
|
||||||
|
injector: Injector, routes: Routes) => {
|
||||||
|
return new Router(
|
||||||
|
null, resolver, urlSerializer, outletMap, location, injector, loader, routes);
|
||||||
|
},
|
||||||
|
deps: [
|
||||||
|
ComponentResolver, UrlSerializer, RouterOutletMap, Location, AppModuleFactoryLoader,
|
||||||
|
Injector, ROUTES
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class RouterTestModule {
|
||||||
|
}
|
|
@ -132,11 +132,6 @@ export declare class Router {
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare const ROUTER_DIRECTIVES: (typeof RouterOutlet | typeof RouterLink | typeof RouterLinkWithHref | typeof RouterLinkActive)[];
|
export declare const ROUTER_DIRECTIVES: (typeof RouterOutlet | typeof RouterLink | typeof RouterLinkWithHref | typeof RouterLinkActive)[];
|
||||||
|
|
||||||
/** @experimental */
|
|
||||||
export declare class RouterAppModule {
|
|
||||||
constructor(injector: Injector);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
export declare type RouterConfig = Route[];
|
export declare type RouterConfig = Route[];
|
||||||
|
|
||||||
|
@ -178,6 +173,11 @@ export declare class RouterLinkWithHref implements OnChanges, OnDestroy {
|
||||||
onClick(button: number, ctrlKey: boolean, metaKey: boolean): boolean;
|
onClick(button: number, ctrlKey: boolean, metaKey: boolean): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @experimental */
|
||||||
|
export declare class RouterModule {
|
||||||
|
constructor(injector: Injector);
|
||||||
|
}
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare class RouterOutlet {
|
export declare class RouterOutlet {
|
||||||
activatedRoute: ActivatedRoute;
|
activatedRoute: ActivatedRoute;
|
||||||
|
|
Loading…
Reference in New Issue