@@ -2,12 +2,13 @@ import {DOWN_ARROW, SPACE, UP_ARROW} from '@angular/cdk/keycodes';
2
2
import { Platform } from '@angular/cdk/platform' ;
3
3
import { createKeyboardEvent , dispatchFakeEvent } from '@angular/cdk/testing' ;
4
4
import { Component , DebugElement } from '@angular/core' ;
5
- import { async , ComponentFixture , inject , TestBed } from '@angular/core/testing' ;
5
+ import { async , ComponentFixture , fakeAsync , inject , TestBed , tick } from '@angular/core/testing' ;
6
6
import { By } from '@angular/platform-browser' ;
7
7
import { MatListModule , MatListOption , MatSelectionList } from './index' ;
8
+ import { FormsModule , NgModel } from '@angular/forms' ;
8
9
9
10
10
- describe ( 'MatSelectionList' , ( ) => {
11
+ describe ( 'MatSelectionList without forms ' , ( ) => {
11
12
describe ( 'with list option' , ( ) => {
12
13
let fixture : ComponentFixture < SelectionListWithListOptions > ;
13
14
let listOptions : DebugElement [ ] ;
@@ -442,6 +443,131 @@ describe('MatSelectionList', () => {
442
443
} ) ;
443
444
} ) ;
444
445
446
+ describe ( 'MatSelectionList with forms' , ( ) => {
447
+
448
+ beforeEach ( async ( ( ) => {
449
+ TestBed . configureTestingModule ( {
450
+ imports : [ MatListModule , FormsModule ] ,
451
+ declarations : [
452
+ SelectionListWithModel
453
+ ]
454
+ } ) ;
455
+
456
+ TestBed . compileComponents ( ) ;
457
+ } ) ) ;
458
+
459
+ describe ( 'and ngModel' , ( ) => {
460
+ let fixture : ComponentFixture < SelectionListWithModel > ;
461
+ let selectionListDebug : DebugElement ;
462
+ let selectionList : MatSelectionList ;
463
+ let listOptions : MatListOption [ ] ;
464
+ let ngModel : NgModel ;
465
+
466
+ beforeEach ( ( ) => {
467
+ fixture = TestBed . createComponent ( SelectionListWithModel ) ;
468
+ fixture . detectChanges ( ) ;
469
+
470
+ selectionListDebug = fixture . debugElement . query ( By . directive ( MatSelectionList ) ) ;
471
+ selectionList = selectionListDebug . componentInstance ;
472
+ ngModel = selectionListDebug . injector . get < NgModel > ( NgModel ) ;
473
+ listOptions = fixture . debugElement . queryAll ( By . directive ( MatListOption ) )
474
+ . map ( optionDebugEl => optionDebugEl . componentInstance ) ;
475
+ } ) ;
476
+
477
+ it ( 'should update the model if an option got selected' , fakeAsync ( ( ) => {
478
+ expect ( fixture . componentInstance . selectedOptions . length )
479
+ . toBe ( 0 , 'Expected no options to be selected by default' ) ;
480
+
481
+ listOptions [ 0 ] . toggle ( ) ;
482
+ fixture . detectChanges ( ) ;
483
+
484
+ tick ( ) ;
485
+
486
+ expect ( fixture . componentInstance . selectedOptions . length )
487
+ . toBe ( 1 , 'Expected first list option to be selected' ) ;
488
+ } ) ) ;
489
+
490
+ it ( 'should update the model if an option got clicked' , fakeAsync ( ( ) => {
491
+ expect ( fixture . componentInstance . selectedOptions . length )
492
+ . toBe ( 0 , 'Expected no options to be selected by default' ) ;
493
+
494
+ dispatchFakeEvent ( listOptions [ 0 ] . _getHostElement ( ) , 'click' ) ;
495
+ fixture . detectChanges ( ) ;
496
+
497
+ tick ( ) ;
498
+
499
+ expect ( fixture . componentInstance . selectedOptions . length )
500
+ . toBe ( 1 , 'Expected first list option to be selected' ) ;
501
+ } ) ) ;
502
+
503
+ it ( 'should update the options if a model value is set' , fakeAsync ( ( ) => {
504
+ expect ( fixture . componentInstance . selectedOptions . length )
505
+ . toBe ( 0 , 'Expected no options to be selected by default' ) ;
506
+
507
+ fixture . componentInstance . selectedOptions = [ 'opt3' ] ;
508
+ fixture . detectChanges ( ) ;
509
+
510
+ tick ( ) ;
511
+
512
+ expect ( fixture . componentInstance . selectedOptions . length )
513
+ . toBe ( 1 , 'Expected first list option to be selected' ) ;
514
+ } ) ) ;
515
+
516
+ it ( 'should set the selection-list to touched on blur' , fakeAsync ( ( ) => {
517
+ expect ( ngModel . touched )
518
+ . toBe ( false , 'Expected the selection-list to be untouched by default.' ) ;
519
+
520
+ dispatchFakeEvent ( selectionListDebug . nativeElement , 'blur' ) ;
521
+ fixture . detectChanges ( ) ;
522
+
523
+ tick ( ) ;
524
+
525
+ expect ( ngModel . touched ) . toBe ( true , 'Expected the selection-list to be touched after blur' ) ;
526
+ } ) ) ;
527
+
528
+ it ( 'should be able to disable the selection-list using the form control' , fakeAsync ( ( ) => {
529
+ expect ( listOptions . every ( option => ! option . disabled ) )
530
+ . toBe ( true , 'Expected every list-option to be enabled' ) ;
531
+
532
+ ngModel . control . disable ( ) ;
533
+ fixture . detectChanges ( ) ;
534
+
535
+ tick ( ) ;
536
+
537
+ expect ( listOptions . every ( option => option . disabled ) )
538
+ . toBe ( true , 'Expected every list-option to be disabled' ) ;
539
+ } ) ) ;
540
+
541
+
542
+ it ( 'should be pristine by default' , fakeAsync ( ( ) => {
543
+ fixture = TestBed . createComponent ( SelectionListWithModel ) ;
544
+ fixture . componentInstance . selectedOptions = [ 'opt2' ] ;
545
+ fixture . detectChanges ( ) ;
546
+
547
+ ngModel =
548
+ fixture . debugElement . query ( By . directive ( MatSelectionList ) ) . injector . get < NgModel > ( NgModel ) ;
549
+ listOptions = fixture . debugElement . queryAll ( By . directive ( MatListOption ) )
550
+ . map ( optionDebugEl => optionDebugEl . componentInstance ) ;
551
+
552
+ // Flush the initial tick to ensure that every action from the ControlValueAccessor
553
+ // happened before the actual test starts.
554
+ tick ( ) ;
555
+
556
+ expect ( ngModel . pristine )
557
+ . toBe ( true , 'Expected the selection-list to be pristine by default.' ) ;
558
+
559
+ listOptions [ 1 ] . toggle ( ) ;
560
+ fixture . detectChanges ( ) ;
561
+
562
+ tick ( ) ;
563
+
564
+ expect ( ngModel . pristine )
565
+ . toBe ( false , 'Expected the selection-list to be dirty after state change.' ) ;
566
+ } ) ) ;
567
+ } ) ;
568
+
569
+ } ) ;
570
+
445
571
446
572
@Component ( { template : `
447
573
<mat-selection-list id="selection-list-1">
@@ -523,3 +649,15 @@ class SelectionListWithSelectedOption {
523
649
</mat-selection-list>` } )
524
650
class SelectionListWithOnlyOneOption {
525
651
}
652
+
653
+ @Component ( {
654
+ template : `
655
+ <mat-selection-list [(ngModel)]="selectedOptions">
656
+ <mat-list-option value="opt1">Option 1</mat-list-option>
657
+ <mat-list-option value="opt2">Option 2</mat-list-option>
658
+ <mat-list-option value="opt3">Option 3</mat-list-option>
659
+ </mat-selection-list>`
660
+ } )
661
+ class SelectionListWithModel {
662
+ selectedOptions : string [ ] = [ ] ;
663
+ }
0 commit comments