1
- import { TestBed , async , ComponentFixture , fakeAsync , tick , inject } from '@angular/core/testing' ;
2
- import { By } from '@angular/platform-browser' ;
3
1
import {
4
2
Component ,
5
3
DebugElement ,
@@ -9,17 +7,26 @@ import {
9
7
ChangeDetectionStrategy ,
10
8
OnInit ,
11
9
} from '@angular/core' ;
10
+ import {
11
+ ControlValueAccessor ,
12
+ FormControl ,
13
+ FormsModule ,
14
+ NG_VALUE_ACCESSOR ,
15
+ ReactiveFormsModule ,
16
+ FormGroup ,
17
+ FormGroupDirective ,
18
+ Validators ,
19
+ } from '@angular/forms' ;
20
+ import { By } from '@angular/platform-browser' ;
12
21
import { NoopAnimationsModule } from '@angular/platform-browser/animations' ;
22
+ import { TestBed , async , ComponentFixture , fakeAsync , tick , inject } from '@angular/core/testing' ;
13
23
import { MdSelectModule } from './index' ;
14
24
import { OverlayContainer } from '../core/overlay/overlay-container' ;
15
25
import { MdSelect } from './select' ;
16
26
import { getMdSelectDynamicMultipleError , getMdSelectNonArrayValueError } from './select-errors' ;
17
27
import { MdOption } from '../core/option/option' ;
18
28
import { Directionality } from '../core/bidi/index' ;
19
29
import { DOWN_ARROW , UP_ARROW , ENTER , SPACE , HOME , END , TAB } from '../core/keyboard/keycodes' ;
20
- import {
21
- ControlValueAccessor , FormControl , FormsModule , NG_VALUE_ACCESSOR , ReactiveFormsModule
22
- } from '@angular/forms' ;
23
30
import { Subject } from 'rxjs/Subject' ;
24
31
import { ViewportRuler } from '../core/overlay/position/viewport-ruler' ;
25
32
import { dispatchFakeEvent , dispatchKeyboardEvent , wrappedErrorMessage } from '@angular/cdk/testing' ;
@@ -66,7 +73,8 @@ describe('MdSelect', () => {
66
73
InvalidSelectInForm ,
67
74
BasicSelectWithoutForms ,
68
75
BasicSelectWithoutFormsPreselected ,
69
- BasicSelectWithoutFormsMultiple
76
+ BasicSelectWithoutFormsMultiple ,
77
+ SelectInsideFormGroup
70
78
] ,
71
79
providers : [
72
80
{ provide : OverlayContainer , useFactory : ( ) => {
@@ -1719,11 +1727,12 @@ describe('MdSelect', () => {
1719
1727
'mat-select-required' , `Expected the mat-select-required class to be set.` ) ;
1720
1728
} ) ;
1721
1729
1722
- it ( 'should set aria-invalid for selects that are invalid' , ( ) => {
1730
+ it ( 'should set aria-invalid for selects that are invalid and touched ' , ( ) => {
1723
1731
expect ( select . getAttribute ( 'aria-invalid' ) )
1724
1732
. toEqual ( 'false' , `Expected aria-invalid attr to be false for valid selects.` ) ;
1725
1733
1726
1734
fixture . componentInstance . isRequired = true ;
1735
+ fixture . componentInstance . control . markAsTouched ( ) ;
1727
1736
fixture . detectChanges ( ) ;
1728
1737
1729
1738
expect ( select . getAttribute ( 'aria-invalid' ) )
@@ -2571,6 +2580,77 @@ describe('MdSelect', () => {
2571
2580
2572
2581
} ) ;
2573
2582
2583
+ describe ( 'error state' , ( ) => {
2584
+ let fixture : ComponentFixture < SelectInsideFormGroup > ;
2585
+ let testComponent : SelectInsideFormGroup ;
2586
+ let select : HTMLElement ;
2587
+
2588
+ beforeEach ( ( ) => {
2589
+ fixture = TestBed . createComponent ( SelectInsideFormGroup ) ;
2590
+ fixture . detectChanges ( ) ;
2591
+ testComponent = fixture . componentInstance ;
2592
+ select = fixture . debugElement . query ( By . css ( 'md-select' ) ) . nativeElement ;
2593
+ } ) ;
2594
+
2595
+ it ( 'should not set the invalid class on a clean select' , ( ) => {
2596
+ expect ( testComponent . formGroup . untouched ) . toBe ( true , 'Expected the form to be untouched.' ) ;
2597
+ expect ( testComponent . formControl . invalid ) . toBe ( true , 'Expected form control to be invalid.' ) ;
2598
+ expect ( select . classList )
2599
+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2600
+ expect ( select . getAttribute ( 'aria-invalid' ) )
2601
+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2602
+ } ) ;
2603
+
2604
+ it ( 'should appear as invalid if it becomes touched' , ( ) => {
2605
+ expect ( select . classList )
2606
+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2607
+ expect ( select . getAttribute ( 'aria-invalid' ) )
2608
+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2609
+
2610
+ testComponent . formControl . markAsTouched ( ) ;
2611
+ fixture . detectChanges ( ) ;
2612
+
2613
+ expect ( select . classList )
2614
+ . toContain ( 'mat-select-invalid' , 'Expected select to appear invalid.' ) ;
2615
+ expect ( select . getAttribute ( 'aria-invalid' ) )
2616
+ . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
2617
+ } ) ;
2618
+
2619
+ it ( 'should not have the invalid class when the select becomes valid' , ( ) => {
2620
+ testComponent . formControl . markAsTouched ( ) ;
2621
+ fixture . detectChanges ( ) ;
2622
+
2623
+ expect ( select . classList )
2624
+ . toContain ( 'mat-select-invalid' , 'Expected select to appear invalid.' ) ;
2625
+ expect ( select . getAttribute ( 'aria-invalid' ) )
2626
+ . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
2627
+
2628
+ testComponent . formControl . setValue ( 'pizza-1' ) ;
2629
+ fixture . detectChanges ( ) ;
2630
+
2631
+ expect ( select . classList )
2632
+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2633
+ expect ( select . getAttribute ( 'aria-invalid' ) )
2634
+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2635
+ } ) ;
2636
+
2637
+ it ( 'should appear as invalid when the parent form group is submitted' , ( ) => {
2638
+ expect ( select . classList )
2639
+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2640
+ expect ( select . getAttribute ( 'aria-invalid' ) )
2641
+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2642
+
2643
+ dispatchFakeEvent ( fixture . debugElement . query ( By . css ( 'form' ) ) . nativeElement , 'submit' ) ;
2644
+ fixture . detectChanges ( ) ;
2645
+
2646
+ expect ( select . classList )
2647
+ . toContain ( 'mat-select-invalid' , 'Expected select to appear invalid.' ) ;
2648
+ expect ( select . getAttribute ( 'aria-invalid' ) )
2649
+ . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
2650
+ } ) ;
2651
+
2652
+ } ) ;
2653
+
2574
2654
} ) ;
2575
2655
2576
2656
@@ -2918,6 +2998,7 @@ class BasicSelectWithTheming {
2918
2998
theme : string ;
2919
2999
}
2920
3000
3001
+
2921
3002
@Component ( {
2922
3003
selector : 'reset-values-select' ,
2923
3004
template : `
@@ -2944,7 +3025,6 @@ class ResetValuesSelect {
2944
3025
@ViewChild ( MdSelect ) select : MdSelect ;
2945
3026
}
2946
3027
2947
-
2948
3028
@Component ( {
2949
3029
template : `
2950
3030
<md-select [formControl]="control">
@@ -3028,6 +3108,25 @@ class InvalidSelectInForm {
3028
3108
}
3029
3109
3030
3110
3111
+ @Component ( {
3112
+ template : `
3113
+ <form [formGroup]="formGroup">
3114
+ <md-select placeholder="Food" formControlName="food">
3115
+ <md-option value="steak-0">Steak</md-option>
3116
+ <md-option value="pizza-1">Pizza</md-option>
3117
+ </md-select>
3118
+ </form>
3119
+ `
3120
+ } )
3121
+ class SelectInsideFormGroup {
3122
+ @ViewChild ( FormGroupDirective ) formGroupDirective : FormGroupDirective ;
3123
+ formControl = new FormControl ( '' , Validators . required ) ;
3124
+ formGroup = new FormGroup ( {
3125
+ food : this . formControl
3126
+ } ) ;
3127
+ }
3128
+
3129
+
3031
3130
@Component ( {
3032
3131
template : `
3033
3132
<md-select placeholder="Food" [(value)]="selectedFood">
0 commit comments