11import { MutationObserverFactory } from '@angular/cdk/observers' ;
22import { dispatchFakeEvent } from '@angular/cdk/testing' ;
33import { Component } from '@angular/core' ;
4- import { ComponentFixture , fakeAsync , flushMicrotasks , TestBed , tick } from '@angular/core/testing' ;
4+ import {
5+ ComponentFixture ,
6+ fakeAsync ,
7+ flush ,
8+ flushMicrotasks ,
9+ TestBed ,
10+ tick ,
11+ } from '@angular/core/testing' ;
512import { FormControl , FormsModule , NgModel , ReactiveFormsModule } from '@angular/forms' ;
613import { defaultRippleAnimationConfig } from '@angular/material/core' ;
714import { By , HAMMER_GESTURE_CONFIG } from '@angular/platform-browser' ;
@@ -773,7 +780,7 @@ describe('MatSlideToggle with forms', () => {
773780 expect ( slideToggleElement . classList ) . toContain ( 'mat-checked' ) ;
774781 } ) ) ;
775782
776- it ( 'should have the correct control state initially and after interaction' , ( ) => {
783+ it ( 'should have the correct control state initially and after interaction' , fakeAsync ( ( ) => {
777784 // The control should start off valid, pristine, and untouched.
778785 expect ( slideToggleModel . valid ) . toBe ( true ) ;
779786 expect ( slideToggleModel . pristine ) . toBe ( true ) ;
@@ -795,13 +802,31 @@ describe('MatSlideToggle with forms', () => {
795802 // also turn touched.
796803 dispatchFakeEvent ( inputElement , 'blur' ) ;
797804 fixture . detectChanges ( ) ;
805+ flushMicrotasks ( ) ;
798806
799807 expect ( slideToggleModel . valid ) . toBe ( true ) ;
800808 expect ( slideToggleModel . pristine ) . toBe ( false ) ;
801809 expect ( slideToggleModel . touched ) . toBe ( true ) ;
802- } ) ;
810+ } ) ) ;
811+
812+ it ( 'should not throw an error when disabling while focused' , fakeAsync ( ( ) => {
813+ expect ( ( ) => {
814+ // Focus the input element because after disabling, the `blur` event should automatically
815+ // fire and not result in a changed after checked exception. Related: #12323
816+ inputElement . focus ( ) ;
817+
818+ // Flush the two nested timeouts from the FocusMonitor that are being created on `focus`.
819+ flush ( ) ;
820+
821+ slideToggle . disabled = true ;
822+ fixture . detectChanges ( ) ;
823+ flushMicrotasks ( ) ;
824+ } ) . not . toThrow ( ) ;
825+ } ) ) ;
826+
827+ it ( 'should not set the control to touched when changing the state programmatically' ,
828+ fakeAsync ( ( ) => {
803829
804- it ( 'should not set the control to touched when changing the state programmatically' , ( ) => {
805830 // The control should start off with being untouched.
806831 expect ( slideToggleModel . touched ) . toBe ( false ) ;
807832
@@ -815,10 +840,11 @@ describe('MatSlideToggle with forms', () => {
815840 // also turn touched.
816841 dispatchFakeEvent ( inputElement , 'blur' ) ;
817842 fixture . detectChanges ( ) ;
843+ flushMicrotasks ( ) ;
818844
819845 expect ( slideToggleModel . touched ) . toBe ( true ) ;
820846 expect ( slideToggleElement . classList ) . toContain ( 'mat-checked' ) ;
821- } ) ;
847+ } ) ) ;
822848
823849 it ( 'should not set the control to touched when changing the model' , fakeAsync ( ( ) => {
824850 // The control should start off with being untouched.
0 commit comments