@@ -16,11 +16,12 @@ import {MdSelect, MdSelectFloatPlaceholderType} from './select';
1616import { MdSelectDynamicMultipleError , MdSelectNonArrayValueError } from './select-errors' ;
1717import { MdOption } from '../core/option/option' ;
1818import { Dir } from '../core/rtl/dir' ;
19+ import { DOWN_ARROW , UP_ARROW } from '../core/keyboard/keycodes' ;
1920import {
2021 ControlValueAccessor , FormControl , FormsModule , NG_VALUE_ACCESSOR , ReactiveFormsModule
2122} from '@angular/forms' ;
2223import { ViewportRuler } from '../core/overlay/position/viewport-ruler' ;
23- import { dispatchFakeEvent } from '../core/testing/dispatch-events' ;
24+ import { dispatchFakeEvent , dispatchKeyboardEvent } from '../core/testing/dispatch-events' ;
2425import { wrappedErrorMessage } from '../core/testing/wrapped-error-message' ;
2526
2627
@@ -1170,6 +1171,81 @@ describe('MdSelect', () => {
11701171 expect ( select . getAttribute ( 'tabindex' ) ) . toEqual ( '0' ) ;
11711172 } ) ;
11721173
1174+ it ( 'should be able to select options via the arrow keys on a closed select' , ( ) => {
1175+ const formControl = fixture . componentInstance . control ;
1176+ const options = fixture . componentInstance . options . toArray ( ) ;
1177+
1178+ expect ( formControl . value ) . toBeFalsy ( 'Expected no initial value.' ) ;
1179+
1180+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1181+
1182+ expect ( options [ 0 ] . selected ) . toBe ( true , 'Expected first option to be selected.' ) ;
1183+ expect ( formControl . value ) . toBe ( options [ 0 ] . value ,
1184+ 'Expected value from first option to have been set on the model.' ) ;
1185+
1186+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1187+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1188+
1189+ // Note that the third option is skipped, because it is disabled.
1190+ expect ( options [ 3 ] . selected ) . toBe ( true , 'Expected fourth option to be selected.' ) ;
1191+ expect ( formControl . value ) . toBe ( options [ 3 ] . value ,
1192+ 'Expected value from fourth option to have been set on the model.' ) ;
1193+
1194+ dispatchKeyboardEvent ( select , 'keydown' , UP_ARROW ) ;
1195+
1196+ expect ( options [ 1 ] . selected ) . toBe ( true , 'Expected second option to be selected.' ) ;
1197+ expect ( formControl . value ) . toBe ( options [ 1 ] . value ,
1198+ 'Expected value from second option to have been set on the model.' ) ;
1199+ } ) ;
1200+
1201+ it ( 'should do nothing if the key manager did not change the active item' , ( ) => {
1202+ const formControl = fixture . componentInstance . control ;
1203+
1204+ expect ( formControl . value ) . toBeNull ( 'Expected form control value to be empty.' ) ;
1205+ expect ( formControl . pristine ) . toBe ( true , 'Expected form control to be clean.' ) ;
1206+
1207+ dispatchKeyboardEvent ( select , 'keydown' , 16 ) ; // Press a random key.
1208+
1209+ expect ( formControl . value ) . toBeNull ( 'Expected form control value to stay empty.' ) ;
1210+ expect ( formControl . pristine ) . toBe ( true , 'Expected form control to stay clean.' ) ;
1211+ } ) ;
1212+
1213+ it ( 'should continue from the selected option when the value is set programmatically' , ( ) => {
1214+ const formControl = fixture . componentInstance . control ;
1215+
1216+ formControl . setValue ( 'eggs-5' ) ;
1217+ fixture . detectChanges ( ) ;
1218+
1219+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1220+
1221+ expect ( formControl . value ) . toBe ( 'pasta-6' ) ;
1222+ expect ( fixture . componentInstance . options . toArray ( ) [ 6 ] . selected ) . toBe ( true ) ;
1223+ } ) ;
1224+
1225+ it ( 'should not cycle through the options if the control is disabled' , ( ) => {
1226+ const formControl = fixture . componentInstance . control ;
1227+
1228+ formControl . setValue ( 'eggs-5' ) ;
1229+ formControl . disable ( ) ;
1230+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1231+
1232+ expect ( formControl . value ) . toBe ( 'eggs-5' , 'Expected value to remain unchaged.' ) ;
1233+ } ) ;
1234+
1235+ it ( 'should not wrap selection around after reaching the end of the options' , ( ) => {
1236+ const lastOption = fixture . componentInstance . options . last ;
1237+
1238+ fixture . componentInstance . options . forEach ( ( ) => {
1239+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1240+ } ) ;
1241+
1242+ expect ( lastOption . selected ) . toBe ( true , 'Expected last option to be selected.' ) ;
1243+
1244+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1245+
1246+ expect ( lastOption . selected ) . toBe ( true , 'Expected last option to stay selected.' ) ;
1247+ } ) ;
1248+
11731249 } ) ;
11741250
11751251 describe ( 'for options' , ( ) => {
0 commit comments