@@ -338,6 +338,95 @@ export function main() {
338
338
339
339
} ) ;
340
340
341
+ describe ( 'select controls' , ( ) => {
342
+ it ( `should support primitive values` , ( ) => {
343
+ const fixture = initTest ( FormControlNameSelect ) ;
344
+ fixture . detectChanges ( ) ;
345
+
346
+ // model -> view
347
+ const select = fixture . debugElement . query ( By . css ( 'select' ) ) ;
348
+ const sfOption = fixture . debugElement . query ( By . css ( 'option' ) ) ;
349
+ expect ( select . nativeElement . value ) . toEqual ( 'SF' ) ;
350
+ expect ( sfOption . nativeElement . selected ) . toBe ( true ) ;
351
+
352
+ select . nativeElement . value = 'NY' ;
353
+ dispatchEvent ( select . nativeElement , 'change' ) ;
354
+ fixture . detectChanges ( ) ;
355
+
356
+ // view -> model
357
+ expect ( sfOption . nativeElement . selected ) . toBe ( false ) ;
358
+ expect ( fixture . componentInstance . form . value ) . toEqual ( { 'city' : 'NY' } ) ;
359
+ } ) ;
360
+
361
+ it ( `should support objects` , ( ) => {
362
+ const fixture = initTest ( FormControlSelectNgValue ) ;
363
+ fixture . detectChanges ( ) ;
364
+
365
+ // model -> view
366
+ const select = fixture . debugElement . query ( By . css ( 'select' ) ) ;
367
+ const sfOption = fixture . debugElement . query ( By . css ( 'option' ) ) ;
368
+ expect ( select . nativeElement . value ) . toEqual ( '0: Object' ) ;
369
+ expect ( sfOption . nativeElement . selected ) . toBe ( true ) ;
370
+ } ) ;
371
+
372
+ it ( 'should throw an error if compareWith is not a function' , ( ) => {
373
+ const fixture = initTest ( FormControlSelectWithCompareFn ) ;
374
+ fixture . componentInstance . compareFn = null ;
375
+ expect ( ( ) => fixture . detectChanges ( ) )
376
+ . toThrowError ( / c o m p a r e W i t h m u s t b e a f u n c t i o n , b u t r e c e i v e d n u l l / ) ;
377
+ } ) ;
378
+
379
+ it ( 'should compare options using provided compareWith function' , ( ) => {
380
+ const fixture = initTest ( FormControlSelectWithCompareFn ) ;
381
+ fixture . detectChanges ( ) ;
382
+
383
+ const select = fixture . debugElement . query ( By . css ( 'select' ) ) ;
384
+ const sfOption = fixture . debugElement . query ( By . css ( 'option' ) ) ;
385
+ expect ( select . nativeElement . value ) . toEqual ( '0: Object' ) ;
386
+ expect ( sfOption . nativeElement . selected ) . toBe ( true ) ;
387
+ } ) ;
388
+ } ) ;
389
+
390
+ describe ( 'select multiple controls' , ( ) => {
391
+ it ( 'should support primitive values' , ( ) => {
392
+ const fixture = initTest ( FormControlSelectMultiple ) ;
393
+ fixture .detectChanges ( ) ;
394
+
395
+ const select = fixture . debugElement . query ( By . css ( 'select' ) ) ;
396
+ const sfOption = fixture . debugElement . query ( By . css ( 'option' ) ) ;
397
+ expect ( select . nativeElement . value ) . toEqual ( `0: 'SF'` ) ;
398
+ expect ( sfOption . nativeElement . selected ) . toBe ( true ) ;
399
+ } ) ;
400
+
401
+ it ( 'should support objects' , ( ) => {
402
+ const fixture = initTest ( FormControlSelectMultipleNgValue ) ;
403
+ fixture . detectChanges ( ) ;
404
+
405
+ const select = fixture . debugElement . query ( By . css ( 'select' ) ) ;
406
+ const sfOption = fixture . debugElement . query ( By . css ( 'option' ) ) ;
407
+ expect ( select . nativeElement . value ) . toEqual ( '0: Object' ) ;
408
+ expect ( sfOption . nativeElement . selected ) . toBe ( true ) ;
409
+ } ) ;
410
+
411
+ it ( 'should throw an error when compareWith is not a function' , ( ) => {
412
+ const fixture = initTest ( FormControlSelectMultipleWithCompareFn ) ;
413
+ fixture . componentInstance . compareFn = null ;
414
+ expect ( ( ) => fixture . detectChanges ( ) )
415
+ . toThrowError ( / c o m p a r e W i t h m u s t b e a f u n c t i o n , b u t r e c e i v e d n u l l / ) ;
416
+ } ) ;
417
+
418
+ it ( 'should compare options using provided compareWith function' , fakeAsync ( ( ) => {
419
+ const fixture = initTest ( FormControlSelectMultipleWithCompareFn ) ;
420
+ fixture . detectChanges ( ) ;
421
+ tick ( ) ;
422
+
423
+ const select = fixture . debugElement . query ( By . css ( 'select' ) ) ;
424
+ const sfOption = fixture . debugElement . query ( By . css ( 'option' ) ) ;
425
+ expect ( select . nativeElement . value ) . toEqual ( '0: Object' ) ;
426
+ expect ( sfOption . nativeElement . selected ) . toBe ( true ) ;
427
+ } ) ) ;
428
+ } ) ;
429
+
341
430
describe ( 'form arrays' , ( ) => {
342
431
it ( 'should support form arrays' , ( ) => {
343
432
const fixture = initTest ( FormArrayComp ) ;
@@ -835,25 +924,6 @@ export function main() {
835
924
expect ( control . value ) . toBe ( false ) ;
836
925
} ) ;
837
926
838
- it ( 'should support <select>' , ( ) => {
839
- const fixture = initTest ( FormControlNameSelect ) ;
840
- fixture . detectChanges ( ) ;
841
-
842
- // model -> view
843
- const select = fixture . debugElement . query ( By . css ( 'select' ) ) ;
844
- const sfOption = fixture . debugElement . query ( By . css ( 'option' ) ) ;
845
- expect ( select . nativeElement . value ) . toEqual ( 'SF' ) ;
846
- expect ( sfOption . nativeElement . selected ) . toBe ( true ) ;
847
-
848
- select . nativeElement . value = 'NY' ;
849
- dispatchEvent ( select . nativeElement , 'change' ) ;
850
- fixture . detectChanges ( ) ;
851
-
852
- // view -> model
853
- expect ( sfOption . nativeElement . selected ) . toBe ( false ) ;
854
- expect ( fixture . componentInstance . form . value ) . toEqual ( { 'city' : 'NY' } ) ;
855
- } ) ;
856
-
857
927
describe ( 'should support <type=number>' , ( ) => {
858
928
it ( 'with basic use case' , ( ) => {
859
929
const fixture = initTest ( FormControlNumberInput ) ;
@@ -2005,6 +2075,82 @@ class FormControlNameSelect {
2005
2075
form = new FormGroup ( { city : new FormControl ( 'SF' ) } ) ;
2006
2076
}
2007
2077
2078
+ @Component ( {
2079
+ selector : 'form-control-select-ngValue' ,
2080
+ template : `
2081
+ <div [formGroup]="form">
2082
+ <select formControlName="city">
2083
+ <option *ngFor="let c of cities" [ngValue]="c">{{c.name}}</option>
2084
+ </select>
2085
+ </div>`
2086
+ } )
2087
+ class FormControlSelectNgValue {
2088
+ cities = [ { id : 1 , name : 'SF' } , { id : 2 , name : 'NY' } ] ;
2089
+ form = new FormGroup ( { city : new FormControl ( this . cities [ 0 ] ) } ) ;
2090
+ }
2091
+
2092
+ @Component ( {
2093
+ selector : 'form-control-select-compare-with' ,
2094
+ template : `
2095
+ <div [formGroup]="form">
2096
+ <select formControlName="city" [compareWith]="compareFn">
2097
+ <option *ngFor="let c of cities" [ngValue]="c">{{c.name}}</option>
2098
+ </select>
2099
+ </div>`
2100
+ } )
2101
+ class FormControlSelectWithCompareFn {
2102
+ compareFn : ( o1 : any , o2 : any ) => boolean = ( o1 : any , o2 : any ) => {
2103
+ return o1 && o2 ? o1 . id === o2 . id : o1 === o2 ;
2104
+ } ;
2105
+ cities = [ { id : 1 , name : 'SF' } , { id : 2 , name : 'NY' } ] ;
2106
+ form = new FormGroup ( { city : new FormControl ( { id : 1 , name : 'SF' } ) } ) ;
2107
+ }
2108
+
2109
+ @Component ( {
2110
+ selector : 'form-control-select-multiple' ,
2111
+ template : `
2112
+ <div [formGroup]="form">
2113
+ <select multiple formControlName="city">
2114
+ <option *ngFor="let c of cities" [value]="c">{{c}}</option>
2115
+ </select>
2116
+ </div>`
2117
+ } )
2118
+ class FormControlSelectMultiple {
2119
+ cities = [ 'SF' , 'NY' ] ;
2120
+ form = new FormGroup ( { city : new FormControl ( [ 'SF' ] ) } ) ;
2121
+ }
2122
+
2123
+ @Component ( {
2124
+ selector : 'form-control-select-multiple' ,
2125
+ template : `
2126
+ <div [formGroup]="form">
2127
+ <select multiple formControlName="city">
2128
+ <option *ngFor="let c of cities" [ngValue]="c">{{c.name}}</option>
2129
+ </select>
2130
+ </div>`
2131
+ } )
2132
+ class FormControlSelectMultipleNgValue {
2133
+ cities = [ { id : 1 , name : 'SF' } , { id : 2 , name : 'NY' } ] ;
2134
+ form = new FormGroup ( { city : new FormControl ( [ this . cities [ 0 ] ] ) } ) ;
2135
+ }
2136
+
2137
+ @Component ( {
2138
+ selector : 'form-control-select-multiple-compare-with' ,
2139
+ template : `
2140
+ <div [formGroup]="form">
2141
+ <select multiple formControlName="city" [compareWith]="compareFn">
2142
+ <option *ngFor="let c of cities" [ngValue]="c">{{c.name}}</option>
2143
+ </select>
2144
+ </div>`
2145
+ } )
2146
+ class FormControlSelectMultipleWithCompareFn {
2147
+ compareFn : ( o1 : any , o2 : any ) => boolean = ( o1 : any , o2 : any ) => {
2148
+ return o1 && o2 ? o1 . id === o2 . id : o1 === o2 ;
2149
+ } ;
2150
+ cities = [ { id : 1 , name : 'SF' } , { id : 2 , name : 'NY' } ] ;
2151
+ form = new FormGroup ( { city : new FormControl ( [ { id : 1 , name : 'SF' } ] ) } ) ;
2152
+ }
2153
+
2008
2154
@Component ( {
2009
2155
selector : 'wrapped-value-form' ,
2010
2156
template : `
0 commit comments