fix(router): throw when component in route config is not defined
Close #3265 Closes #3569
This commit is contained in:
@ -19,9 +19,17 @@ import {
|
|||||||
isFunction,
|
isFunction,
|
||||||
StringWrapper,
|
StringWrapper,
|
||||||
BaseException,
|
BaseException,
|
||||||
|
Type,
|
||||||
getTypeNameForDebugging
|
getTypeNameForDebugging
|
||||||
} from 'angular2/src/facade/lang';
|
} from 'angular2/src/facade/lang';
|
||||||
import {RouteConfig, AsyncRoute, Route, Redirect, RouteDefinition} from './route_config_impl';
|
import {
|
||||||
|
RouteConfig,
|
||||||
|
AsyncRoute,
|
||||||
|
Route,
|
||||||
|
AuxRoute,
|
||||||
|
Redirect,
|
||||||
|
RouteDefinition
|
||||||
|
} from './route_config_impl';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {Injectable} from 'angular2/di';
|
import {Injectable} from 'angular2/di';
|
||||||
import {normalizeRouteConfig} from './route_config_nomalizer';
|
import {normalizeRouteConfig} from './route_config_nomalizer';
|
||||||
@ -44,6 +52,13 @@ export class RouteRegistry {
|
|||||||
config(parentComponent: any, config: RouteDefinition): void {
|
config(parentComponent: any, config: RouteDefinition): void {
|
||||||
config = normalizeRouteConfig(config);
|
config = normalizeRouteConfig(config);
|
||||||
|
|
||||||
|
// this is here because Dart type guard reasons
|
||||||
|
if (config instanceof Route) {
|
||||||
|
assertComponentExists(config.component, config.path);
|
||||||
|
} else if (config instanceof AuxRoute) {
|
||||||
|
assertComponentExists(config.component, config.path);
|
||||||
|
}
|
||||||
|
|
||||||
var recognizer: RouteRecognizer = this._rules.get(parentComponent);
|
var recognizer: RouteRecognizer = this._rules.get(parentComponent);
|
||||||
|
|
||||||
if (isBlank(recognizer)) {
|
if (isBlank(recognizer)) {
|
||||||
@ -269,3 +284,9 @@ function assertTerminalComponent(component, path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assertComponentExists(component: Type, path: string): void {
|
||||||
|
if (!isType(component)) {
|
||||||
|
throw new BaseException(`Component for route "${path}" is not defined, or is not a class.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,6 +16,7 @@ import {Component, Directive, View} from 'angular2/annotations';
|
|||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
import {bind} from 'angular2/di';
|
import {bind} from 'angular2/di';
|
||||||
import {DOCUMENT_TOKEN} from 'angular2/src/render/render';
|
import {DOCUMENT_TOKEN} from 'angular2/src/render/render';
|
||||||
|
import {Type} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
routerInjectables,
|
routerInjectables,
|
||||||
|
@ -7,13 +7,15 @@ import {
|
|||||||
expect,
|
expect,
|
||||||
inject,
|
inject,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
SpyObject
|
SpyObject,
|
||||||
|
IS_DARTIUM
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
|
|
||||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
|
import {Type} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {RouteRegistry} from 'angular2/src/router/route_registry';
|
import {RouteRegistry} from 'angular2/src/router/route_registry';
|
||||||
import {RouteConfig, Route, AsyncRoute} from 'angular2/src/router/route_config_decorator';
|
import {RouteConfig, Route, AuxRoute, AsyncRoute} from 'angular2/src/router/route_config_decorator';
|
||||||
import {stringifyInstruction} from 'angular2/src/router/instruction';
|
import {stringifyInstruction} from 'angular2/src/router/instruction';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
@ -185,6 +187,20 @@ export function main() {
|
|||||||
.toThrowError('Unexpected "..." before the end of the path for "home/.../fun/".');
|
.toThrowError('Unexpected "..." before the end of the path for "home/.../fun/".');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should throw if a config has a component that is not defined', () => {
|
||||||
|
expect(() => registry.config(RootHostCmp, new Route({path: '/', component: null})))
|
||||||
|
.toThrowError('Component for route "/" is not defined, or is not a class.');
|
||||||
|
expect(() => registry.config(RootHostCmp, new AuxRoute({path: '/', component: null})))
|
||||||
|
.toThrowError('Component for route "/" is not defined, or is not a class.');
|
||||||
|
|
||||||
|
// This would never happen in Dart
|
||||||
|
if (!IS_DARTIUM) {
|
||||||
|
expect(() => registry.config(RootHostCmp, new Route({path: '/', component:<Type>(<any>4)})))
|
||||||
|
.toThrowError('Component for route "/" is not defined, or is not a class.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('should match matrix params on child components and query params on the root component',
|
it('should match matrix params on child components and query params on the root component',
|
||||||
inject([AsyncTestCompleter], (async) => {
|
inject([AsyncTestCompleter], (async) => {
|
||||||
registry.config(RootHostCmp, new Route({path: '/first/...', component: DummyParentCmp}));
|
registry.config(RootHostCmp, new Route({path: '/first/...', component: DummyParentCmp}));
|
||||||
|
Reference in New Issue
Block a user