From 903a0f05130b6cd0548ea139e2a4e8210a6f1a01 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Mon, 10 Aug 2015 13:05:08 -0700 Subject: [PATCH] fix(router): throw when component in route config is not defined Close #3265 Closes #3569 --- modules/angular2/src/router/route_registry.ts | 23 ++++++++++++++++++- .../angular2/test/router/route_config_spec.ts | 1 + .../test/router/route_registry_spec.ts | 20 ++++++++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/modules/angular2/src/router/route_registry.ts b/modules/angular2/src/router/route_registry.ts index e450975599..fa73497918 100644 --- a/modules/angular2/src/router/route_registry.ts +++ b/modules/angular2/src/router/route_registry.ts @@ -19,9 +19,17 @@ import { isFunction, StringWrapper, BaseException, + Type, getTypeNameForDebugging } 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 {Injectable} from 'angular2/di'; import {normalizeRouteConfig} from './route_config_nomalizer'; @@ -44,6 +52,13 @@ export class RouteRegistry { config(parentComponent: any, config: RouteDefinition): void { 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); 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.`); + } +} diff --git a/modules/angular2/test/router/route_config_spec.ts b/modules/angular2/test/router/route_config_spec.ts index 3d8fc3243b..7d53624d2e 100644 --- a/modules/angular2/test/router/route_config_spec.ts +++ b/modules/angular2/test/router/route_config_spec.ts @@ -16,6 +16,7 @@ import {Component, Directive, View} from 'angular2/annotations'; import {DOM} from 'angular2/src/dom/dom_adapter'; import {bind} from 'angular2/di'; import {DOCUMENT_TOKEN} from 'angular2/src/render/render'; +import {Type} from 'angular2/src/facade/lang'; import { routerInjectables, diff --git a/modules/angular2/test/router/route_registry_spec.ts b/modules/angular2/test/router/route_registry_spec.ts index 17aa6a2167..43ae784cca 100644 --- a/modules/angular2/test/router/route_registry_spec.ts +++ b/modules/angular2/test/router/route_registry_spec.ts @@ -7,13 +7,15 @@ import { expect, inject, beforeEach, - SpyObject + SpyObject, + IS_DARTIUM } from 'angular2/test_lib'; import {Promise, PromiseWrapper} from 'angular2/src/facade/async'; +import {Type} from 'angular2/src/facade/lang'; 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'; export function main() { @@ -185,6 +187,20 @@ export function main() { .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:(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', inject([AsyncTestCompleter], (async) => { registry.config(RootHostCmp, new Route({path: '/first/...', component: DummyParentCmp}));