@@ -8,14 +8,17 @@ import {
88 fakeAsync ,
99 tick ,
1010} from '@angular/core/testing' ;
11+ // TODO(iveysaur): Update to @angular/forms when we have rc.2
12+ import { NgControl } from '@angular/common' ;
1113import { TestComponentBuilder , ComponentFixture } from '@angular/compiler/testing' ;
1214import { Component , DebugElement , provide } from '@angular/core' ;
1315import { By } from '@angular/platform-browser' ;
1416import {
1517 MD_BUTTON_TOGGLE_DIRECTIVES ,
1618 MdButtonToggleGroup ,
1719 MdButtonToggle ,
18- MdButtonToggleGroupMultiple
20+ MdButtonToggleGroupMultiple ,
21+ MdButtonToggleChange ,
1922} from './button-toggle' ;
2023import {
2124 MdUniqueSelectionDispatcher
@@ -189,6 +192,138 @@ describe('MdButtonToggle', () => {
189192 } ) ;
190193 } ) ;
191194
195+ describe ( 'button toggle group with ngModel' , ( ) => {
196+ let fixture : ComponentFixture < ButtonToggleGroupWithNgModel > ;
197+ let groupDebugElement : DebugElement ;
198+ let groupNativeElement : HTMLElement ;
199+ let buttonToggleDebugElements : DebugElement [ ] ;
200+ let buttonToggleNativeElements : HTMLElement [ ] ;
201+ let groupInstance : MdButtonToggleGroup ;
202+ let buttonToggleInstances : MdButtonToggle [ ] ;
203+ let testComponent : ButtonToggleGroupWithNgModel ;
204+ let groupNgControl : NgControl ;
205+
206+ beforeEach ( async ( ( ) => {
207+ builder . createAsync ( ButtonToggleGroupWithNgModel ) . then ( f => {
208+ fixture = f ;
209+ fixture . detectChanges ( ) ;
210+
211+ testComponent = fixture . debugElement . componentInstance ;
212+
213+ groupDebugElement = fixture . debugElement . query ( By . directive ( MdButtonToggleGroup ) ) ;
214+ groupNativeElement = groupDebugElement . nativeElement ;
215+ groupInstance = groupDebugElement . injector . get ( MdButtonToggleGroup ) ;
216+ groupNgControl = groupDebugElement . injector . get ( NgControl ) ;
217+
218+ buttonToggleDebugElements = fixture . debugElement . queryAll ( By . directive ( MdButtonToggle ) ) ;
219+ buttonToggleNativeElements =
220+ buttonToggleDebugElements . map ( debugEl => debugEl . nativeElement ) ;
221+ buttonToggleInstances = buttonToggleDebugElements . map ( debugEl => debugEl . componentInstance ) ;
222+ } ) ;
223+ } ) ) ;
224+
225+ it ( 'should set individual radio names based on the group name' , ( ) => {
226+ expect ( groupInstance . name ) . toBeTruthy ( ) ;
227+ for ( let buttonToggle of buttonToggleInstances ) {
228+ expect ( buttonToggle . name ) . toBe ( groupInstance . name ) ;
229+ }
230+
231+ groupInstance . name = 'new name' ;
232+ for ( let buttonToggle of buttonToggleInstances ) {
233+ expect ( buttonToggle . name ) . toBe ( groupInstance . name ) ;
234+ }
235+ } ) ;
236+
237+ it ( 'should check the corresponding button toggle on a group value change' , ( ) => {
238+ expect ( groupInstance . value ) . toBeFalsy ( ) ;
239+ for ( let buttonToggle of buttonToggleInstances ) {
240+ expect ( buttonToggle . checked ) . toBeFalsy ( ) ;
241+ }
242+
243+ groupInstance . value = 'red' ;
244+ for ( let buttonToggle of buttonToggleInstances ) {
245+ expect ( buttonToggle . checked ) . toBe ( groupInstance . value === buttonToggle . value ) ;
246+ }
247+ expect ( groupInstance . selected . value ) . toBe ( groupInstance . value ) ;
248+ } ) ;
249+
250+ it ( 'should have the correct ngControl state initially and after interaction' , fakeAsync ( ( ) => {
251+ expect ( groupNgControl . valid ) . toBe ( true ) ;
252+ expect ( groupNgControl . pristine ) . toBe ( true ) ;
253+ expect ( groupNgControl . touched ) . toBe ( false ) ;
254+
255+ buttonToggleInstances [ 1 ] . checked = true ;
256+ fixture . detectChanges ( ) ;
257+ tick ( ) ;
258+
259+ expect ( groupNgControl . valid ) . toBe ( true ) ;
260+ expect ( groupNgControl . pristine ) . toBe ( false ) ;
261+ expect ( groupNgControl . touched ) . toBe ( false ) ;
262+
263+ let nativeRadioLabel = buttonToggleDebugElements [ 2 ] . query ( By . css ( 'label' ) ) . nativeElement ;
264+ nativeRadioLabel . click ( ) ;
265+ fixture . detectChanges ( ) ;
266+ tick ( ) ;
267+
268+ expect ( groupNgControl . valid ) . toBe ( true ) ;
269+ expect ( groupNgControl . pristine ) . toBe ( false ) ;
270+ expect ( groupNgControl . touched ) . toBe ( true ) ;
271+ } ) ) ;
272+
273+ it ( 'should update the ngModel value when selecting a button toggle' , fakeAsync ( ( ) => {
274+ buttonToggleInstances [ 1 ] . checked = true ;
275+ fixture . detectChanges ( ) ;
276+
277+ tick ( ) ;
278+
279+ expect ( testComponent . modelValue ) . toBe ( 'green' ) ;
280+ } ) ) ;
281+ } ) ;
282+
283+ describe ( 'button toggle group with ngModel and change event' , ( ) => {
284+ let fixture : ComponentFixture < ButtonToggleGroupWithNgModel > ;
285+ let groupDebugElement : DebugElement ;
286+ let groupNativeElement : HTMLElement ;
287+ let buttonToggleDebugElements : DebugElement [ ] ;
288+ let buttonToggleNativeElements : HTMLElement [ ] ;
289+ let groupInstance : MdButtonToggleGroup ;
290+ let buttonToggleInstances : MdButtonToggle [ ] ;
291+ let testComponent : ButtonToggleGroupWithNgModel ;
292+ let groupNgControl : NgControl ;
293+
294+ beforeEach ( async ( ( ) => {
295+ builder . createAsync ( ButtonToggleGroupWithNgModel ) . then ( f => {
296+ fixture = f ;
297+
298+ testComponent = fixture . debugElement . componentInstance ;
299+
300+ groupDebugElement = fixture . debugElement . query ( By . directive ( MdButtonToggleGroup ) ) ;
301+ groupNativeElement = groupDebugElement . nativeElement ;
302+ groupInstance = groupDebugElement . injector . get ( MdButtonToggleGroup ) ;
303+ groupNgControl = groupDebugElement . injector . get ( NgControl ) ;
304+
305+ buttonToggleDebugElements = fixture . debugElement . queryAll ( By . directive ( MdButtonToggle ) ) ;
306+ buttonToggleNativeElements =
307+ buttonToggleDebugElements . map ( debugEl => debugEl . nativeElement ) ;
308+ buttonToggleInstances = buttonToggleDebugElements . map ( debugEl => debugEl . componentInstance ) ;
309+
310+ fixture . detectChanges ( ) ;
311+ } ) ;
312+ } ) ) ;
313+
314+ it ( 'should update the model before firing change event' , fakeAsync ( ( ) => {
315+ expect ( testComponent . modelValue ) . toBeUndefined ( ) ;
316+ expect ( testComponent . lastEvent ) . toBeUndefined ( ) ;
317+
318+ groupInstance . value = 'red' ;
319+ fixture . detectChanges ( ) ;
320+
321+ tick ( ) ;
322+ expect ( testComponent . modelValue ) . toBe ( 'red' ) ;
323+ expect ( testComponent . lastEvent . value ) . toBe ( 'red' ) ;
324+ } ) ) ;
325+ } ) ;
326+
192327 describe ( 'inside of a multiple selection group' , ( ) => {
193328 let fixture : ComponentFixture < ButtonTogglesInsideButtonToggleGroupMultiple > ;
194329 let groupDebugElement : DebugElement ;
@@ -318,6 +453,26 @@ class ButtonTogglesInsideButtonToggleGroup {
318453 groupValue : string = null ;
319454}
320455
456+ @Component ( {
457+ directives : [ MD_BUTTON_TOGGLE_DIRECTIVES ] ,
458+ template : `
459+ <md-button-toggle-group [(ngModel)]="modelValue" (change)="lastEvent = $event">
460+ <md-button-toggle *ngFor="let option of options" [value]="option.value">
461+ {{option.label}}
462+ </md-button-toggle>
463+ </md-button-toggle-group>
464+ `
465+ } )
466+ class ButtonToggleGroupWithNgModel {
467+ modelValue : string ;
468+ options = [
469+ { label : 'Red' , value : 'red' } ,
470+ { label : 'Green' , value : 'green' } ,
471+ { label : 'Blue' , value : 'blue' } ,
472+ ] ;
473+ lastEvent : MdButtonToggleChange ;
474+ }
475+
321476@Component ( {
322477 directives : [ MD_BUTTON_TOGGLE_DIRECTIVES ] ,
323478 template : `
0 commit comments