@@ -31,6 +31,7 @@ import {Subject} from 'rxjs/Subject';
3131import { ViewportRuler } from '../core/overlay/position/viewport-ruler' ;
3232import { dispatchFakeEvent , dispatchKeyboardEvent , wrappedErrorMessage } from '@angular/cdk/testing' ;
3333import { ScrollDispatcher } from '../core/overlay/scroll/scroll-dispatcher' ;
34+ import { MD_ERROR_GLOBAL_OPTIONS , ErrorOptions } from '../core/error/error-options' ;
3435import {
3536 FloatPlaceholderType ,
3637 MD_PLACEHOLDER_GLOBAL_OPTIONS
@@ -74,7 +75,8 @@ describe('MdSelect', () => {
7475 BasicSelectWithoutForms ,
7576 BasicSelectWithoutFormsPreselected ,
7677 BasicSelectWithoutFormsMultiple ,
77- SelectInsideFormGroup
78+ SelectInsideFormGroup ,
79+ CustomErrorBehaviorSelect
7880 ] ,
7981 providers : [
8082 { provide : OverlayContainer , useFactory : ( ) => {
@@ -2660,6 +2662,46 @@ describe('MdSelect', () => {
26602662 . toBe ( 'true' , 'Expected aria-invalid to be set to true.' ) ;
26612663 } ) ;
26622664
2665+ it ( 'should be able to override the error matching behavior via an @Input' , ( ) => {
2666+ fixture . destroy ( ) ;
2667+
2668+ const customErrorFixture = TestBed . createComponent ( CustomErrorBehaviorSelect ) ;
2669+ const component = customErrorFixture . componentInstance ;
2670+ const matcher = jasmine . createSpy ( 'error state matcher' ) . and . returnValue ( true ) ;
2671+
2672+ customErrorFixture . detectChanges ( ) ;
2673+
2674+ expect ( component . control . invalid ) . toBe ( false ) ;
2675+ expect ( component . select . _isErrorState ( ) ) . toBe ( false ) ;
2676+
2677+ customErrorFixture . componentInstance . errorStateMatcher = matcher ;
2678+ customErrorFixture . detectChanges ( ) ;
2679+
2680+ expect ( component . select . _isErrorState ( ) ) . toBe ( true ) ;
2681+ expect ( matcher ) . toHaveBeenCalled ( ) ;
2682+ } ) ;
2683+
2684+ it ( 'should be able to override the error matching behavior via the injection token' , ( ) => {
2685+ const errorOptions : ErrorOptions = {
2686+ errorStateMatcher : jasmine . createSpy ( 'error state matcher' ) . and . returnValue ( true )
2687+ } ;
2688+
2689+ fixture . destroy ( ) ;
2690+
2691+ TestBed . resetTestingModule ( ) . configureTestingModule ( {
2692+ imports : [ MdSelectModule , ReactiveFormsModule , FormsModule , NoopAnimationsModule ] ,
2693+ declarations : [ SelectInsideFormGroup ] ,
2694+ providers : [ { provide : MD_ERROR_GLOBAL_OPTIONS , useValue : errorOptions } ] ,
2695+ } ) ;
2696+
2697+ const errorFixture = TestBed . createComponent ( SelectInsideFormGroup ) ;
2698+ const component = errorFixture . componentInstance ;
2699+
2700+ errorFixture . detectChanges ( ) ;
2701+
2702+ expect ( component . select . _isErrorState ( ) ) . toBe ( true ) ;
2703+ expect ( errorOptions . errorStateMatcher ) . toHaveBeenCalled ( ) ;
2704+ } ) ;
26632705 } ) ;
26642706
26652707} ) ;
@@ -3132,6 +3174,7 @@ class InvalidSelectInForm {
31323174} )
31333175class SelectInsideFormGroup {
31343176 @ViewChild ( FormGroupDirective ) formGroupDirective : FormGroupDirective ;
3177+ @ViewChild ( MdSelect ) select : MdSelect ;
31353178 formControl = new FormControl ( '' , Validators . required ) ;
31363179 formGroup = new FormGroup ( {
31373180 food : this . formControl
@@ -3197,3 +3240,23 @@ class BasicSelectWithoutFormsMultiple {
31973240
31983241 @ViewChild ( MdSelect ) select : MdSelect ;
31993242}
3243+
3244+ @Component ( {
3245+ template : `
3246+ <md-select placeholder="Food" [formControl]="control" [errorStateMatcher]="errorStateMatcher">
3247+ <md-option *ngFor="let food of foods" [value]="food.value">
3248+ {{ food.viewValue }}
3249+ </md-option>
3250+ </md-select>
3251+ `
3252+ } )
3253+ class CustomErrorBehaviorSelect {
3254+ @ViewChild ( MdSelect ) select : MdSelect ;
3255+ control = new FormControl ( ) ;
3256+ foods : any [ ] = [
3257+ { value : 'steak-0' , viewValue : 'Steak' } ,
3258+ { value : 'pizza-1' , viewValue : 'Pizza' } ,
3259+ ] ;
3260+ errorStateMatcher = ( ) => false ;
3261+ }
3262+
0 commit comments