1
1
import { QueryList } from '@angular/core' ;
2
- import { FocusKeyManager } from './focus-key-manager' ;
2
+ import { fakeAsync , tick } from '@angular/core/testing' ;
3
+ import { FocusKeyManager , FOCUS_KEY_MANAGER_DEBOUNCE_INTERVAL } from './focus-key-manager' ;
3
4
import { DOWN_ARROW , UP_ARROW , TAB , HOME , END } from '../keyboard/keycodes' ;
4
5
import { ListKeyManager } from './list-key-manager' ;
5
6
import { ActiveDescendantKeyManager } from './activedescendant-key-manager' ;
6
7
7
8
class FakeFocusable {
8
9
disabled = false ;
9
10
focus ( ) { }
11
+
12
+ getFocusableLabel ( ) {
13
+ return this . _label ;
14
+ }
15
+
16
+ constructor ( private _label ?: string ) { }
10
17
}
11
18
12
19
class FakeHighlightable {
@@ -21,6 +28,7 @@ class FakeQueryList<T> extends QueryList<T> {
21
28
toArray ( ) {
22
29
return this . items ;
23
30
}
31
+ get first ( ) { return this . items [ 0 ] ; }
24
32
}
25
33
26
34
export class FakeEvent {
@@ -394,9 +402,9 @@ describe('Key managers', () => {
394
402
395
403
beforeEach ( ( ) => {
396
404
itemList . items = [
397
- new FakeFocusable ( ) ,
398
- new FakeFocusable ( ) ,
399
- new FakeFocusable ( )
405
+ new FakeFocusable ( 'one' ) ,
406
+ new FakeFocusable ( 'two' ) ,
407
+ new FakeFocusable ( 'three' )
400
408
] ;
401
409
402
410
keyManager = new FocusKeyManager ( itemList ) ;
@@ -409,40 +417,81 @@ describe('Key managers', () => {
409
417
spyOn ( itemList . items [ 2 ] , 'focus' ) ;
410
418
} ) ;
411
419
412
- it ( 'should focus subsequent items when down arrow is pressed' , ( ) => {
413
- keyManager . onKeydown ( DOWN_ARROW_EVENT ) ;
420
+ it ( 'should focus subsequent items when down arrow is pressed' , ( ) => {
421
+ keyManager . onKeydown ( DOWN_ARROW_EVENT ) ;
414
422
415
- expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
416
- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
417
- expect ( itemList . items [ 2 ] . focus ) . not . toHaveBeenCalled ( ) ;
423
+ expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
424
+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
425
+ expect ( itemList . items [ 2 ] . focus ) . not . toHaveBeenCalled ( ) ;
418
426
419
- keyManager . onKeydown ( DOWN_ARROW_EVENT ) ;
420
- expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
421
- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
422
- expect ( itemList . items [ 2 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
423
- } ) ;
427
+ keyManager . onKeydown ( DOWN_ARROW_EVENT ) ;
428
+ expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
429
+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
430
+ expect ( itemList . items [ 2 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
431
+ } ) ;
424
432
425
- it ( 'should focus previous items when up arrow is pressed' , ( ) => {
426
- keyManager . onKeydown ( DOWN_ARROW_EVENT ) ;
433
+ it ( 'should focus previous items when up arrow is pressed' , ( ) => {
434
+ keyManager . onKeydown ( DOWN_ARROW_EVENT ) ;
427
435
428
- expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
429
- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
436
+ expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
437
+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
430
438
431
- keyManager . onKeydown ( UP_ARROW_EVENT ) ;
439
+ keyManager . onKeydown ( UP_ARROW_EVENT ) ;
432
440
433
- expect ( itemList . items [ 0 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
434
- expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
435
- } ) ;
441
+ expect ( itemList . items [ 0 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
442
+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalledTimes ( 1 ) ;
443
+ } ) ;
436
444
437
- it ( 'should allow setting the focused item without calling focus' , ( ) => {
438
- expect ( keyManager . activeItemIndex )
439
- . toBe ( 0 , `Expected first item of the list to be active.` ) ;
445
+ it ( 'should allow setting the focused item without calling focus' , ( ) => {
446
+ expect ( keyManager . activeItemIndex )
447
+ . toBe ( 0 , `Expected first item of the list to be active.` ) ;
440
448
441
- keyManager . updateActiveItemIndex ( 1 ) ;
442
- expect ( keyManager . activeItemIndex )
443
- . toBe ( 1 , `Expected activeItemIndex to update after calling updateActiveItemIndex().` ) ;
444
- expect ( itemList . items [ 1 ] . focus ) . not . toHaveBeenCalledTimes ( 1 ) ;
445
- } ) ;
449
+ keyManager . updateActiveItemIndex ( 1 ) ;
450
+ expect ( keyManager . activeItemIndex )
451
+ . toBe ( 1 , `Expected activeItemIndex to update after calling updateActiveItemIndex().` ) ;
452
+ expect ( itemList . items [ 1 ] . focus ) . not . toHaveBeenCalledTimes ( 1 ) ;
453
+ } ) ;
454
+
455
+ it ( 'should debounce the input key presses' , fakeAsync ( ( ) => {
456
+ keyManager . onKeydown ( new FakeEvent ( 79 ) as KeyboardEvent ) ; // types "o"
457
+ keyManager . onKeydown ( new FakeEvent ( 78 ) as KeyboardEvent ) ; // types "n"
458
+ keyManager . onKeydown ( new FakeEvent ( 69 ) as KeyboardEvent ) ; // types "e"
459
+
460
+ expect ( itemList . items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
461
+
462
+ tick ( FOCUS_KEY_MANAGER_DEBOUNCE_INTERVAL ) ;
463
+
464
+ expect ( itemList . items [ 0 ] . focus ) . toHaveBeenCalled ( ) ;
465
+ } ) ) ;
466
+
467
+ it ( 'should focus the first item that starts with a letter' , fakeAsync ( ( ) => {
468
+ keyManager . onKeydown ( new FakeEvent ( 84 ) as KeyboardEvent ) ; // types "t"
469
+
470
+ tick ( FOCUS_KEY_MANAGER_DEBOUNCE_INTERVAL ) ;
471
+
472
+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalled ( ) ;
473
+ } ) ) ;
474
+
475
+ it ( 'should focus the first item that starts with sequence of letters' , fakeAsync ( ( ) => {
476
+ keyManager . onKeydown ( new FakeEvent ( 84 ) as KeyboardEvent ) ; // types "t"
477
+ keyManager . onKeydown ( new FakeEvent ( 72 ) as KeyboardEvent ) ; // types "h"
478
+
479
+ tick ( FOCUS_KEY_MANAGER_DEBOUNCE_INTERVAL ) ;
480
+
481
+ expect ( itemList . items [ 1 ] . focus ) . not . toHaveBeenCalled ( ) ;
482
+ expect ( itemList . items [ 2 ] . focus ) . toHaveBeenCalled ( ) ;
483
+ } ) ) ;
484
+
485
+ it ( 'should cancel any pending timers if a non-input key is pressed' , fakeAsync ( ( ) => {
486
+ keyManager . onKeydown ( new FakeEvent ( 84 ) as KeyboardEvent ) ; // types "t"
487
+ keyManager . onKeydown ( new FakeEvent ( 72 ) as KeyboardEvent ) ; // types "h"
488
+ keyManager . onKeydown ( DOWN_ARROW_EVENT ) ;
489
+
490
+ tick ( FOCUS_KEY_MANAGER_DEBOUNCE_INTERVAL ) ;
491
+
492
+ expect ( itemList . items [ 2 ] . focus ) . not . toHaveBeenCalled ( ) ;
493
+ expect ( itemList . items [ 1 ] . focus ) . toHaveBeenCalled ( ) ;
494
+ } ) ) ;
446
495
447
496
} ) ;
448
497
0 commit comments