@@ -9,8 +9,10 @@ import {first} from '../rxjs/index';
99
1010
1111class FakeFocusable {
12+ constructor ( private _label = '' ) { }
1213 disabled = false ;
1314 focus ( ) { }
15+ getLabel ( ) { return this . _label ; }
1416}
1517
1618class FakeHighlightable {
@@ -25,6 +27,7 @@ class FakeQueryList<T> extends QueryList<T> {
2527 toArray ( ) {
2628 return this . items ;
2729 }
30+ get first ( ) { return this . items [ 0 ] ; }
2831}
2932
3033
@@ -43,7 +46,7 @@ describe('Key managers', () => {
4346 downArrow : createKeyboardEvent ( 'keydown' , DOWN_ARROW ) ,
4447 upArrow : createKeyboardEvent ( 'keydown' , UP_ARROW ) ,
4548 tab : createKeyboardEvent ( 'keydown' , TAB ) ,
46- unsupported : createKeyboardEvent ( 'keydown' , 65 ) // corresponds to the letter "a"
49+ unsupported : createKeyboardEvent ( 'keydown' , 192 ) // corresponds to the tilde character (~)
4750 } ;
4851 } ) ;
4952
@@ -52,7 +55,11 @@ describe('Key managers', () => {
5255 let keyManager : ListKeyManager < FakeFocusable > ;
5356
5457 beforeEach ( ( ) => {
55- itemList . items = [ new FakeFocusable ( ) , new FakeFocusable ( ) , new FakeFocusable ( ) ] ;
58+ itemList . items = [
59+ new FakeFocusable ( 'one' ) ,
60+ new FakeFocusable ( 'two' ) ,
61+ new FakeFocusable ( 'three' )
62+ ] ;
5663 keyManager = new ListKeyManager < FakeFocusable > ( itemList ) ;
5764
5865 // first item is already focused
@@ -383,6 +390,55 @@ describe('Key managers', () => {
383390
384391 } ) ;
385392
393+ describe ( 'typeahead mode' , ( ) => {
394+ const debounceInterval = 300 ;
395+
396+ beforeEach ( ( ) => {
397+ keyManager . withTypeAhead ( debounceInterval ) ;
398+ keyManager . setActiveItem ( - 1 ) ;
399+ } ) ;
400+
401+ it ( 'should debounce the input key presses' , fakeAsync ( ( ) => {
402+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 79 ) ) ; // types "o"
403+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 78 ) ) ; // types "n"
404+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 69 ) ) ; // types "e"
405+
406+ expect ( keyManager . activeItem ) . not . toBe ( itemList . items [ 0 ] ) ;
407+
408+ tick ( debounceInterval ) ;
409+
410+ expect ( keyManager . activeItem ) . toBe ( itemList . items [ 0 ] ) ;
411+ } ) ) ;
412+
413+ it ( 'should focus the first item that starts with a letter' , fakeAsync ( ( ) => {
414+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 84 ) ) ; // types "t"
415+
416+ tick ( debounceInterval ) ;
417+
418+ expect ( keyManager . activeItem ) . toBe ( itemList . items [ 1 ] ) ;
419+ } ) ) ;
420+
421+ it ( 'should focus the first item that starts with sequence of letters' , fakeAsync ( ( ) => {
422+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 84 ) ) ; // types "t"
423+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 72 ) ) ; // types "h"
424+
425+ tick ( debounceInterval ) ;
426+
427+ expect ( keyManager . activeItem ) . toBe ( itemList . items [ 2 ] ) ;
428+ } ) ) ;
429+
430+ it ( 'should cancel any pending timers if a navigation key is pressed' , fakeAsync ( ( ) => {
431+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 84 ) ) ; // types "t"
432+ keyManager . onKeydown ( createKeyboardEvent ( 'keydown' , 72 ) ) ; // types "h"
433+ keyManager . onKeydown ( fakeKeyEvents . downArrow ) ;
434+
435+ tick ( debounceInterval ) ;
436+
437+ expect ( keyManager . activeItem ) . toBe ( itemList . items [ 0 ] ) ;
438+ } ) ) ;
439+
440+ } ) ;
441+
386442 } ) ;
387443
388444 describe ( 'FocusKeyManager' , ( ) => {
@@ -400,40 +456,40 @@ describe('Key managers', () => {
400456 spyOn ( itemList . items [ 2 ] , 'focus' ) ;
401457 } ) ;
402458
403- it ( 'should focus subsequent items when down arrow is pressed' , ( ) => {
404- keyManager . onKeydown ( fakeKeyEvents . downArrow ) ;
459+ it ( 'should focus subsequent items when down arrow is pressed' , ( ) => {
460+ keyManager . onKeydown ( fakeKeyEvents . downArrow ) ;
405461
406- expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
407- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
408- expect ( itemList . items [ 2 ] . focus ) . not . toHaveBeenCalled ( ) ;
462+ expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
463+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
464+ expect ( itemList . items [ 2 ] . focus ) . not . toHaveBeenCalled ( ) ;
409465
410- keyManager . onKeydown ( fakeKeyEvents . downArrow ) ;
411- expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
412- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
413- expect ( itemList . items [ 2 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
414- } ) ;
466+ keyManager . onKeydown ( fakeKeyEvents . downArrow ) ;
467+ expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
468+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
469+ expect ( itemList . items [ 2 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
470+ } ) ;
415471
416- it ( 'should focus previous items when up arrow is pressed' , ( ) => {
417- keyManager . onKeydown ( fakeKeyEvents . downArrow ) ;
472+ it ( 'should focus previous items when up arrow is pressed' , ( ) => {
473+ keyManager . onKeydown ( fakeKeyEvents . downArrow ) ;
418474
419- expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
420- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
475+ expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
476+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
421477
422- keyManager . onKeydown ( fakeKeyEvents . upArrow ) ;
478+ keyManager . onKeydown ( fakeKeyEvents . upArrow ) ;
423479
424- expect ( itemList . items [ 0 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
425- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
426- } ) ;
480+ expect ( itemList . items [ 0 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
481+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
482+ } ) ;
427483
428- it ( 'should allow setting the focused item without calling focus' , ( ) => {
429- expect ( keyManager . activeItemIndex )
430- . toBe ( 0 , `Expected first item of the list to be active.` ) ;
484+ it ( 'should allow setting the focused item without calling focus' , ( ) => {
485+ expect ( keyManager . activeItemIndex )
486+ . toBe ( 0 , `Expected first item of the list to be active.` ) ;
431487
432- keyManager . updateActiveItemIndex ( 1 ) ;
433- expect ( keyManager . activeItemIndex )
434- . toBe ( 1 , `Expected activeItemIndex to update after calling updateActiveItemIndex().` ) ;
435- expect ( itemList . items [ 1 ] . focus ) . not . toHaveBeenCalledTimes ( 1 ) ;
436- } ) ;
488+ keyManager . updateActiveItemIndex ( 1 ) ;
489+ expect ( keyManager . activeItemIndex )
490+ . toBe ( 1 , `Expected activeItemIndex to update after calling updateActiveItemIndex().` ) ;
491+ expect ( itemList . items [ 1 ] . focus ) . not . toHaveBeenCalledTimes ( 1 ) ;
492+ } ) ;
437493
438494 } ) ;
439495
0 commit comments