@@ -28,7 +28,8 @@ import {
2828 extendObject ,
2929 FloatPlaceholderType ,
3030 MAT_PLACEHOLDER_GLOBAL_OPTIONS ,
31- MatOption
31+ MatOption ,
32+ ErrorStateMatcher ,
3233} from '@angular/material/core' ;
3334import { MatFormFieldModule } from '@angular/material/form-field' ;
3435import { By } from '@angular/platform-browser' ;
@@ -91,6 +92,7 @@ describe('MatSelect', () => {
9192 FalsyValueSelect ,
9293 SelectInsideFormGroup ,
9394 NgModelCompareWithSelect ,
95+ CustomErrorBehaviorSelect ,
9496 ] ,
9597 providers : [
9698 { provide : OverlayContainer , useFactory : ( ) => {
@@ -2831,6 +2833,47 @@ describe('MatSelect', () => {
28312833 expect ( select . getAttribute ( 'aria-invalid' ) )
28322834 . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
28332835 } ) ;
2836+
2837+ it ( 'should be able to override the error matching behavior via an @Input' , ( ) => {
2838+ fixture . destroy ( ) ;
2839+
2840+ const customErrorFixture = TestBed . createComponent ( CustomErrorBehaviorSelect ) ;
2841+ const component = customErrorFixture . componentInstance ;
2842+ const matcher = jasmine . createSpy ( 'error state matcher' ) . and . returnValue ( true ) ;
2843+
2844+ customErrorFixture . detectChanges ( ) ;
2845+
2846+ expect ( component . control . invalid ) . toBe ( false ) ;
2847+ expect ( component . select . errorState ) . toBe ( false ) ;
2848+
2849+ customErrorFixture . componentInstance . errorStateMatcher = { isErrorState : matcher } ;
2850+ customErrorFixture . detectChanges ( ) ;
2851+
2852+ expect ( component . select . errorState ) . toBe ( true ) ;
2853+ expect ( matcher ) . toHaveBeenCalled ( ) ;
2854+ } ) ;
2855+
2856+ it ( 'should be able to override the error matching behavior via the injection token' , ( ) => {
2857+ const errorStateMatcher : ErrorStateMatcher = {
2858+ isErrorState : jasmine . createSpy ( 'error state matcher' ) . and . returnValue ( true )
2859+ } ;
2860+
2861+ fixture . destroy ( ) ;
2862+
2863+ TestBed . resetTestingModule ( ) . configureTestingModule ( {
2864+ imports : [ MatSelectModule , ReactiveFormsModule , FormsModule , NoopAnimationsModule ] ,
2865+ declarations : [ SelectInsideFormGroup ] ,
2866+ providers : [ { provide : ErrorStateMatcher , useValue : errorStateMatcher } ] ,
2867+ } ) ;
2868+
2869+ const errorFixture = TestBed . createComponent ( SelectInsideFormGroup ) ;
2870+ const component = errorFixture . componentInstance ;
2871+
2872+ errorFixture . detectChanges ( ) ;
2873+
2874+ expect ( component . select . errorState ) . toBe ( true ) ;
2875+ expect ( errorStateMatcher . isErrorState ) . toHaveBeenCalled ( ) ;
2876+ } ) ;
28342877 } ) ;
28352878
28362879 describe ( 'compareWith behavior' , ( ) => {
@@ -3411,6 +3454,7 @@ class InvalidSelectInForm {
34113454} )
34123455class SelectInsideFormGroup {
34133456 @ViewChild ( FormGroupDirective ) formGroupDirective : FormGroupDirective ;
3457+ @ViewChild ( MatSelect ) select : MatSelect ;
34143458 formControl = new FormControl ( '' , Validators . required ) ;
34153459 formGroup = new FormGroup ( {
34163460 food : this . formControl
@@ -3545,3 +3589,22 @@ class NgModelCompareWithSelect {
35453589 this . selectedFood = extendObject ( { } , newValue ) ;
35463590 }
35473591}
3592+
3593+ @Component ( {
3594+ template : `
3595+ <mat-select placeholder="Food" [formControl]="control" [errorStateMatcher]="errorStateMatcher">
3596+ <mat-option *ngFor="let food of foods" [value]="food.value">
3597+ {{ food.viewValue }}
3598+ </mat-option>
3599+ </mat-select>
3600+ `
3601+ } )
3602+ class CustomErrorBehaviorSelect {
3603+ @ViewChild ( MatSelect ) select : MatSelect ;
3604+ control = new FormControl ( ) ;
3605+ foods : any [ ] = [
3606+ { value : 'steak-0' , viewValue : 'Steak' } ,
3607+ { value : 'pizza-1' , viewValue : 'Pizza' } ,
3608+ ] ;
3609+ errorStateMatcher : ErrorStateMatcher ;
3610+ }
0 commit comments