From a488238c0c0e775373920423d0a6a6d56384f459 Mon Sep 17 00:00:00 2001 From: Hans Larsen Date: Thu, 7 Apr 2016 09:15:14 -0700 Subject: [PATCH] fix: do not throw when there's no sidenav. Fixes #269. --- src/components/sidenav/sidenav.spec.ts | 48 ++++++++++++++++++-------- src/components/sidenav/sidenav.ts | 8 ----- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/components/sidenav/sidenav.spec.ts b/src/components/sidenav/sidenav.spec.ts index a3e50fdcea33..91464f6ebeb6 100644 --- a/src/components/sidenav/sidenav.spec.ts +++ b/src/components/sidenav/sidenav.spec.ts @@ -13,6 +13,7 @@ import { import {XHR} from 'angular2/src/compiler/xhr'; import { Component, + Type, ViewMetadata } from 'angular2/core'; @@ -28,7 +29,7 @@ function fakeAsyncAdaptor(fn: () => void) { /** * Create a ComponentFixture from the builder. This takes a template and a style for sidenav. */ -function createFixture(builder: TestComponentBuilder, +function createFixture(appType: Type, builder: TestComponentBuilder, template: string, style: string): ComponentFixture { let fixture: ComponentFixture = null; // Remove the styles (which remove the animations/transitions). @@ -38,7 +39,7 @@ function createFixture(builder: TestComponentBuilder, styles: [style], directives: [MdSidenav], })) - .createAsync(BasicTestApp).then((f: ComponentFixture) => { fixture = f; }); + .createAsync(appType).then((f: ComponentFixture) => { fixture = f; }); tick(); return fixture; @@ -81,7 +82,7 @@ export function main() { describe('methods', () => { it('should be able to open and close', fakeAsyncAdaptor(() => { - let fixture = createFixture(builder, template, style); + let fixture = createFixture(BasicTestApp, builder, template, style); let testComponent: BasicTestApp = fixture.debugElement.componentInstance; let openButtonElement = fixture.debugElement.query(By.css('.open')); @@ -130,12 +131,12 @@ export function main() { })); it('open/close() return a promise that resolves after animation end', fakeAsyncAdaptor(() => { - let fixture = createFixture(builder, template, style); + let fixture = createFixture(BasicTestApp, builder, template, style); let sidenav: MdSidenav = fixture.debugElement .query(By.directive(MdSidenav)).componentInstance; let called = false; - sidenav.open().then((_: any) => { + sidenav.open().then(() => { called = true; }); @@ -145,7 +146,7 @@ export function main() { expect(called).toBe(true); called = false; - sidenav.close().then((_: any) => { + sidenav.close().then(() => { called = true; }); @@ -157,7 +158,7 @@ export function main() { })); it('open/close() twice returns the same promise', fakeAsyncAdaptor(() => { - let fixture = createFixture(builder, template, style); + let fixture = createFixture(BasicTestApp, builder, template, style); let sidenav: MdSidenav = fixture.debugElement .query(By.directive(MdSidenav)).componentInstance; @@ -172,19 +173,18 @@ export function main() { })); it('open() then close() cancel animations when called too fast', fakeAsyncAdaptor(() => { - let fixture = createFixture(builder, template, style); + let fixture = createFixture(BasicTestApp, builder, template, style); let sidenav: MdSidenav = fixture.debugElement .query(By.directive(MdSidenav)).componentInstance; - let closePromise: Promise; let openCalled = false; let openCancelled = false; let closeCalled = false; - sidenav.open().then((_: any) => { openCalled = true; }, () => { openCancelled = true; }); + sidenav.open().then(() => { openCalled = true; }, () => { openCancelled = true; }); // We do not call transition end, close directly. - closePromise = sidenav.close().then((_: any) => { closeCalled = true; }); + sidenav.close().then(() => { closeCalled = true; }); endSidenavTransition(fixture); tick(); @@ -196,7 +196,7 @@ export function main() { })); it('close() then open() cancel animations when called too fast', fakeAsyncAdaptor(() => { - let fixture = createFixture(builder, template, style); + let fixture = createFixture(BasicTestApp, builder, template, style); let sidenav: MdSidenav = fixture.debugElement .query(By.directive(MdSidenav)).componentInstance; @@ -210,9 +210,9 @@ export function main() { tick(); // Then close and check behavior. - sidenav.close().then((_: any) => { closeCalled = true; }, () => { closeCancelled = true; }); + sidenav.close().then(() => { closeCalled = true; }, () => { closeCancelled = true; }); // We do not call transition end, open directly. - sidenav.open().then((_: any) => { openCalled = true; }); + sidenav.open().then(() => { openCalled = true; }); endSidenavTransition(fixture); tick(); @@ -222,10 +222,30 @@ export function main() { expect(openCalled).toBe(true); tick(); })); + + it('does not throw when created without a sidenav', fakeAsyncAdaptor(() => { + expect(() => { + createFixture(SidenavLayoutNoSidenavTestApp, builder, template, style); + }).not.toThrow(); + })); }); }); } + +/** Test component that contains an MdSidenavLayout but no MdSidenav. */ +@Component({ + selector: 'test-app', + directives: [MD_SIDENAV_DIRECTIVES], + template: ` + + + `, +}) +class SidenavLayoutNoSidenavTestApp { +} + + /** Test component that contains an MdSidenavLayout and one MdSidenav. */ @Component({ selector: 'test-app', diff --git a/src/components/sidenav/sidenav.ts b/src/components/sidenav/sidenav.ts index e6e99460e344..28a50ac25dda 100644 --- a/src/components/sidenav/sidenav.ts +++ b/src/components/sidenav/sidenav.ts @@ -19,11 +19,6 @@ import {Dir} from '../../core/rtl/dir'; import {PromiseCompleter} from 'angular2/src/facade/promise'; -/** - * Exception thrown when a MdSidenavLayout is missing both sidenavs. - */ -export class MdMissingSidenavException extends BaseException {} - /** * Exception thrown when two MdSidenav are matching the same side. */ @@ -286,9 +281,6 @@ export class MdSidenavLayout implements AfterContentInit { */ private _validateDrawers() { this._start = this._end = null; - if (this._sidenavs.length === 0) { - throw new MdMissingSidenavException(); - } // Ensure that we have at most one start and one end sidenav. this._sidenavs.forEach(sidenav => {