diff --git a/src/lib/tabs/tab-group.spec.ts b/src/lib/tabs/tab-group.spec.ts index 7a46afaf54b..b4c844482a9 100644 --- a/src/lib/tabs/tab-group.spec.ts +++ b/src/lib/tabs/tab-group.spec.ts @@ -129,6 +129,15 @@ describe('MdTabGroup', () => { fixture.detectChanges(); expect(component.selectedIndex).toBe(2); }); + + it('should not crash when setting the selected index to NaN', () => { + let component = fixture.debugElement.componentInstance; + + expect(() => { + component.selectedIndex = NaN; + fixture.detectChanges(); + }).not.toThrow(); + }); }); describe('dynamic binding tabs', () => { @@ -244,19 +253,19 @@ describe('MdTabGroup', () => { * Checks that the `selectedIndex` has been updated; checks that the label and body have their * respective `active` classes */ - function checkSelectedIndex(index: number, fixture: ComponentFixture) { + function checkSelectedIndex(expectedIndex: number, fixture: ComponentFixture) { fixture.detectChanges(); let tabComponent: MdTabGroup = fixture.debugElement .query(By.css('md-tab-group')).componentInstance; - expect(tabComponent.selectedIndex).toBe(index); + expect(tabComponent.selectedIndex).toBe(expectedIndex); let tabLabelElement = fixture.debugElement - .query(By.css(`.md-tab-label:nth-of-type(${index + 1})`)).nativeElement; + .query(By.css(`.md-tab-label:nth-of-type(${expectedIndex + 1})`)).nativeElement; expect(tabLabelElement.classList.contains('md-tab-label-active')).toBe(true); let tabContentElement = fixture.debugElement - .query(By.css(`md-tab-body:nth-of-type(${index + 1})`)).nativeElement; + .query(By.css(`md-tab-body:nth-of-type(${expectedIndex + 1})`)).nativeElement; expect(tabContentElement.classList.contains('md-tab-body-active')).toBe(true); } diff --git a/src/lib/tabs/tab-group.ts b/src/lib/tabs/tab-group.ts index 975eb136177..f229aaf5b19 100644 --- a/src/lib/tabs/tab-group.ts +++ b/src/lib/tabs/tab-group.ts @@ -116,9 +116,11 @@ export class MdTabGroup { * a new selected tab should transition in (from the left or right). */ ngAfterContentChecked(): void { - // Clamp the next selected index to the bounds of 0 and the tabs length. + // Clamp the next selected index to the bounds of 0 and the tabs length. Note the `|| 0`, which + // ensures that values like NaN can't get through and which would otherwise throw the + // component into an infinite loop (since Math.max(NaN, 0) === NaN). this._indexToSelect = - Math.min(this._tabs.length - 1, Math.max(this._indexToSelect, 0)); + Math.min(this._tabs.length - 1, Math.max(this._indexToSelect || 0, 0)); // If there is a change in selected index, emit a change event. Should not trigger if // the selected index has not yet been initialized.