@@ -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
@@ -1210,6 +1211,81 @@ describe('MdSelect', () => {
12101211 expect ( select . getAttribute ( 'tabindex' ) ) . toEqual ( '0' ) ;
12111212 } ) ;
12121213
1214+ it ( 'should be able to select options via the arrow keys on a closed select' , ( ) => {
1215+ const formControl = fixture . componentInstance . control ;
1216+ const options = fixture . componentInstance . options . toArray ( ) ;
1217+
1218+ expect ( formControl . value ) . toBeFalsy ( 'Expected no initial value.' ) ;
1219+
1220+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1221+
1222+ expect ( options [ 0 ] . selected ) . toBe ( true , 'Expected first option to be selected.' ) ;
1223+ expect ( formControl . value ) . toBe ( options [ 0 ] . value ,
1224+ 'Expected value from first option to have been set on the model.' ) ;
1225+
1226+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1227+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1228+
1229+ // Note that the third option is skipped, because it is disabled.
1230+ expect ( options [ 3 ] . selected ) . toBe ( true , 'Expected fourth option to be selected.' ) ;
1231+ expect ( formControl . value ) . toBe ( options [ 3 ] . value ,
1232+ 'Expected value from fourth option to have been set on the model.' ) ;
1233+
1234+ dispatchKeyboardEvent ( select , 'keydown' , UP_ARROW ) ;
1235+
1236+ expect ( options [ 1 ] . selected ) . toBe ( true , 'Expected second option to be selected.' ) ;
1237+ expect ( formControl . value ) . toBe ( options [ 1 ] . value ,
1238+ 'Expected value from second option to have been set on the model.' ) ;
1239+ } ) ;
1240+
1241+ it ( 'should do nothing if the key manager did not change the active item' , ( ) => {
1242+ const formControl = fixture . componentInstance . control ;
1243+
1244+ expect ( formControl . value ) . toBeNull ( 'Expected form control value to be empty.' ) ;
1245+ expect ( formControl . pristine ) . toBe ( true , 'Expected form control to be clean.' ) ;
1246+
1247+ dispatchKeyboardEvent ( select , 'keydown' , 16 ) ; // Press a random key.
1248+
1249+ expect ( formControl . value ) . toBeNull ( 'Expected form control value to stay empty.' ) ;
1250+ expect ( formControl . pristine ) . toBe ( true , 'Expected form control to stay clean.' ) ;
1251+ } ) ;
1252+
1253+ it ( 'should continue from the selected option when the value is set programmatically' , ( ) => {
1254+ const formControl = fixture . componentInstance . control ;
1255+
1256+ formControl . setValue ( 'eggs-5' ) ;
1257+ fixture . detectChanges ( ) ;
1258+
1259+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1260+
1261+ expect ( formControl . value ) . toBe ( 'pasta-6' ) ;
1262+ expect ( fixture . componentInstance . options . toArray ( ) [ 6 ] . selected ) . toBe ( true ) ;
1263+ } ) ;
1264+
1265+ it ( 'should not cycle through the options if the control is disabled' , ( ) => {
1266+ const formControl = fixture . componentInstance . control ;
1267+
1268+ formControl . setValue ( 'eggs-5' ) ;
1269+ formControl . disable ( ) ;
1270+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1271+
1272+ expect ( formControl . value ) . toBe ( 'eggs-5' , 'Expected value to remain unchaged.' ) ;
1273+ } ) ;
1274+
1275+ it ( 'should not wrap selection around after reaching the end of the options' , ( ) => {
1276+ const lastOption = fixture . componentInstance . options . last ;
1277+
1278+ fixture . componentInstance . options . forEach ( ( ) => {
1279+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1280+ } ) ;
1281+
1282+ expect ( lastOption . selected ) . toBe ( true , 'Expected last option to be selected.' ) ;
1283+
1284+ dispatchKeyboardEvent ( select , 'keydown' , DOWN_ARROW ) ;
1285+
1286+ expect ( lastOption . selected ) . toBe ( true , 'Expected last option to stay selected.' ) ;
1287+ } ) ;
1288+
12131289 } ) ;
12141290
12151291 describe ( 'for options' , ( ) => {
0 commit comments