From 8aec215ca06ade2af7d7670148e97dc637f09632 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Sep 2015 07:49:02 -0700 Subject: [PATCH] fix(router): throw when generating non-terminal link Closes #3979 Closes #4092 --- modules/angular2/src/router/route_registry.ts | 20 ++++++++++++++++++- .../test/router/route_registry_spec.ts | 12 ++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/angular2/src/router/route_registry.ts b/modules/angular2/src/router/route_registry.ts index e7ffa30f60..4115213786 100644 --- a/modules/angular2/src/router/route_registry.ts +++ b/modules/angular2/src/router/route_registry.ts @@ -200,6 +200,7 @@ export class RouteRegistry { generate(linkParams: any[], parentComponent: any): Instruction { let segments = []; let componentCursor = parentComponent; + var lastInstructionIsTerminal = false; for (let i = 0; i < linkParams.length; i += 1) { let segment = linkParams[i]; @@ -233,9 +234,26 @@ export class RouteRegistry { } segments.push(response); componentCursor = response.componentType; + lastInstructionIsTerminal = response.terminal; } - var instruction: Instruction = this._generateRedirects(componentCursor); + var instruction: Instruction = null; + + if (!lastInstructionIsTerminal) { + instruction = this._generateRedirects(componentCursor); + + if (isPresent(instruction)) { + let lastInstruction = instruction; + while (isPresent(lastInstruction.child)) { + lastInstruction = lastInstruction.child; + } + lastInstructionIsTerminal = lastInstruction.component.terminal; + } + if (!lastInstructionIsTerminal) { + throw new BaseException( + `Link "${ListWrapper.toJSON(linkParams)}" does not resolve to a terminal instruction.`); + } + } while (segments.length > 0) { diff --git a/modules/angular2/test/router/route_registry_spec.ts b/modules/angular2/test/router/route_registry_spec.ts index 04ee4a3b26..4ee6271a60 100644 --- a/modules/angular2/test/router/route_registry_spec.ts +++ b/modules/angular2/test/router/route_registry_spec.ts @@ -79,9 +79,8 @@ export function main() { expect(url).toEqual('first/one/second/two'); }); - it('should geneate params as an empty StringMap when no params are given', () => { - registry.config(RootHostCmp, - new Route({path: '/test/...', component: DummyParentParamCmp, as: 'test'})); + it('should generate params as an empty StringMap when no params are given', () => { + registry.config(RootHostCmp, new Route({path: '/test', component: DummyCmpA, as: 'test'})); var instruction = registry.generate(['test'], RootHostCmp); expect(instruction.component.params).toEqual({}); }); @@ -232,6 +231,13 @@ export function main() { } }); + it('should throw when linkParams are not terminal', () => { + registry.config(RootHostCmp, + new Route({path: '/first/...', component: DummyParentCmp, as: 'first'})); + expect(() => { registry.generate(['first'], RootHostCmp); }) + .toThrowError('Link "["first"]" does not resolve to a terminal instruction.'); + }); + 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}));