1- import { TestBed , async , ComponentFixture , fakeAsync , tick , inject } from '@angular/core/testing' ;
2- import { By } from '@angular/platform-browser' ;
31import {
42 Component ,
53 DebugElement ,
@@ -9,17 +7,26 @@ import {
97 ChangeDetectionStrategy ,
108 OnInit ,
119} 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' ;
1221import { NoopAnimationsModule } from '@angular/platform-browser/animations' ;
22+ import { TestBed , async , ComponentFixture , fakeAsync , tick , inject } from '@angular/core/testing' ;
1323import { MdSelectModule } from './index' ;
1424import { OverlayContainer } from '../core/overlay/overlay-container' ;
1525import { MdSelect } from './select' ;
1626import { getMdSelectDynamicMultipleError , getMdSelectNonArrayValueError } from './select-errors' ;
1727import { MdOption } from '../core/option/option' ;
1828import { Directionality } from '../core/bidi/index' ;
1929import { 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' ;
2330import { Subject } from 'rxjs/Subject' ;
2431import { ViewportRuler } from '../core/overlay/position/viewport-ruler' ;
2532import { dispatchFakeEvent , dispatchKeyboardEvent , wrappedErrorMessage } from '@angular/cdk/testing' ;
@@ -63,7 +70,8 @@ describe('MdSelect', () => {
6370 ResetValuesSelect ,
6471 FalsyValueSelect ,
6572 SelectWithGroups ,
66- InvalidSelectInForm
73+ InvalidSelectInForm ,
74+ SelectInsideFormGroup
6775 ] ,
6876 providers : [
6977 { provide : OverlayContainer , useFactory : ( ) => {
@@ -1584,11 +1592,12 @@ describe('MdSelect', () => {
15841592 'mat-select-required' , `Expected the mat-select-required class to be set.` ) ;
15851593 } ) ;
15861594
1587- it ( 'should set aria-invalid for selects that are invalid' , ( ) => {
1595+ it ( 'should set aria-invalid for selects that are invalid and touched ' , ( ) => {
15881596 expect ( select . getAttribute ( 'aria-invalid' ) )
15891597 . toEqual ( 'false' , `Expected aria-invalid attr to be false for valid selects.` ) ;
15901598
15911599 fixture . componentInstance . isRequired = true ;
1600+ fixture . componentInstance . control . markAsTouched ( ) ;
15921601 fixture . detectChanges ( ) ;
15931602
15941603 expect ( select . getAttribute ( 'aria-invalid' ) )
@@ -2437,6 +2446,77 @@ describe('MdSelect', () => {
24372446
24382447 } ) ;
24392448
2449+ describe ( 'error state' , ( ) => {
2450+ let fixture : ComponentFixture < SelectInsideFormGroup > ;
2451+ let testComponent : SelectInsideFormGroup ;
2452+ let select : HTMLElement ;
2453+
2454+ beforeEach ( ( ) => {
2455+ fixture = TestBed . createComponent ( SelectInsideFormGroup ) ;
2456+ fixture . detectChanges ( ) ;
2457+ testComponent = fixture . componentInstance ;
2458+ select = fixture . debugElement . query ( By . css ( 'md-select' ) ) . nativeElement ;
2459+ } ) ;
2460+
2461+ it ( 'should not set the invalid class on a clean select' , ( ) => {
2462+ expect ( testComponent . formGroup . untouched ) . toBe ( true , 'Expected the form to be untouched.' ) ;
2463+ expect ( testComponent . formControl . invalid ) . toBe ( true , 'Expected form control to be invalid.' ) ;
2464+ expect ( select . classList )
2465+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2466+ expect ( select . getAttribute ( 'aria-invalid' ) )
2467+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2468+ } ) ;
2469+
2470+ it ( 'should appear as invalid if it becomes touched' , ( ) => {
2471+ expect ( select . classList )
2472+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2473+ expect ( select . getAttribute ( 'aria-invalid' ) )
2474+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2475+
2476+ testComponent . formControl . markAsTouched ( ) ;
2477+ fixture . detectChanges ( ) ;
2478+
2479+ expect ( select . classList )
2480+ . toContain ( 'mat-select-invalid' , 'Expected select to appear invalid.' ) ;
2481+ expect ( select . getAttribute ( 'aria-invalid' ) )
2482+ . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
2483+ } ) ;
2484+
2485+ it ( 'should not have the invalid class when the select becomes valid' , ( ) => {
2486+ testComponent . formControl . markAsTouched ( ) ;
2487+ fixture . detectChanges ( ) ;
2488+
2489+ expect ( select . classList )
2490+ . toContain ( 'mat-select-invalid' , 'Expected select to appear invalid.' ) ;
2491+ expect ( select . getAttribute ( 'aria-invalid' ) )
2492+ . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
2493+
2494+ testComponent . formControl . setValue ( 'pizza-1' ) ;
2495+ fixture . detectChanges ( ) ;
2496+
2497+ expect ( select . classList )
2498+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2499+ expect ( select . getAttribute ( 'aria-invalid' ) )
2500+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2501+ } ) ;
2502+
2503+ it ( 'should appear as invalid when the parent form group is submitted' , ( ) => {
2504+ expect ( select . classList )
2505+ . not . toContain ( 'mat-select-invalid' , 'Expected select not to appear invalid.' ) ;
2506+ expect ( select . getAttribute ( 'aria-invalid' ) )
2507+ . toBe ( 'false' , 'Expected aria-invalid to be set to false.' ) ;
2508+
2509+ dispatchFakeEvent ( fixture . debugElement . query ( By . css ( 'form' ) ) . nativeElement , 'submit' ) ;
2510+ fixture . detectChanges ( ) ;
2511+
2512+ expect ( select . classList )
2513+ . toContain ( 'mat-select-invalid' , 'Expected select to appear invalid.' ) ;
2514+ expect ( select . getAttribute ( 'aria-invalid' ) )
2515+ . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
2516+ } ) ;
2517+
2518+ } ) ;
2519+
24402520} ) ;
24412521
24422522
@@ -2784,6 +2864,7 @@ class BasicSelectWithTheming {
27842864 theme : string ;
27852865}
27862866
2867+
27872868@Component ( {
27882869 selector : 'reset-values-select' ,
27892870 template : `
@@ -2810,7 +2891,6 @@ class ResetValuesSelect {
28102891 @ViewChild ( MdSelect ) select : MdSelect ;
28112892}
28122893
2813-
28142894@Component ( {
28152895 template : `
28162896 <md-select [formControl]="control">
@@ -2892,3 +2972,22 @@ class SelectWithGroups {
28922972class InvalidSelectInForm {
28932973 value : any ;
28942974}
2975+
2976+
2977+ @Component ( {
2978+ template : `
2979+ <form [formGroup]="formGroup">
2980+ <md-select placeholder="Food" formControlName="food">
2981+ <md-option value="steak-0">Steak</md-option>
2982+ <md-option value="pizza-1">Pizza</md-option>
2983+ </md-select>
2984+ </form>
2985+ `
2986+ } )
2987+ class SelectInsideFormGroup {
2988+ @ViewChild ( FormGroupDirective ) formGroupDirective : FormGroupDirective ;
2989+ formControl = new FormControl ( '' , Validators . required ) ;
2990+ formGroup = new FormGroup ( {
2991+ food : this . formControl
2992+ } ) ;
2993+ }
0 commit comments