@@ -242,27 +242,56 @@ describe('ValidationMessagesComponent', () => {
242242 . toThrowError ( `There is no suitable arv-validation-message element to show the 'required' error of ''` ) ;
243243 } ) ;
244244
245- xit ( `validates child validation message as they are shown or hidden through *ngIf` , ( ) => {
246- @Component ( {
247- template : `
248- <arv-validation-messages [for]="firstNameControl">
249- <arv-validation-message *ngIf="show" [for]="lastNameControl" key="required"></arv-validation-message>
250- </arv-validation-messages>`
251- } )
252- class TestHostComponent {
253- firstNameControl : FormControl = new FormControl ( null ) ;
254- lastNameControl : FormControl = new FormControl ( null ) ;
255- show = false ;
256- }
257-
258- TestBed . configureTestingModule ( {
259- imports : [ ReactiveFormsModule ] ,
260- declarations : [ ValidationMessagesComponent , ValidationMessageComponent , TestHostComponent ]
245+ describe ( '' , ( ) => {
246+ let onerrorBeforeTest : ErrorEventHandler ;
247+ beforeEach ( ( ) => {
248+ onerrorBeforeTest = window . onerror ;
249+ } ) ;
250+ afterEach ( ( ) => {
251+ window . onerror = onerrorBeforeTest ;
261252 } ) ;
262253
263- const fixture = TestBed . createComponent ( TestHostComponent ) ;
264- fixture . detectChanges ( ) ;
265- fixture . componentInstance . show = true ;
266- expect ( ( ) => fixture . detectChanges ( ) ) . toThrowError ( ) ;
254+ it ( `validates child validation message as they are shown or hidden through *ngIf` , ( done : Function ) => {
255+ @Component ( {
256+ template : `
257+ <arv-validation-messages [for]="firstNameControl">
258+ <arv-validation-message *ngIf="show" [for]="lastNameControl" key="required"></arv-validation-message>
259+ </arv-validation-messages>`
260+ } )
261+ class TestHostComponent {
262+ firstNameControl : FormControl = new FormControl ( null ) ;
263+ lastNameControl : FormControl = new FormControl ( null ) ;
264+ show = false ;
265+ }
266+
267+ TestBed . configureTestingModule ( {
268+ imports : [ ReactiveFormsModule ] ,
269+ declarations : [ ValidationMessagesComponent , ValidationMessageComponent , TestHostComponent ]
270+ } ) ;
271+
272+ // We can't simply expect().toThrowError(), because in RxJS 6, any error inside of 'next'
273+ // is asynchronously thrown, instead of synchronously as before. So these errors will never reach the call stack
274+ // of the expect() function. The observables also isn't exposed, and therefore we need to resort to catching
275+ // the error through window.onerror.
276+ window . onerror = event => {
277+ if ( isErrorEvent ( event ) ) {
278+ expect ( event . error . message ) . toEqual ( `A arv-validation-messages element with key 'required' attempts to show messages ` +
279+ `for a FormControl that is not declared in the parent arv-validation-messages element.` ) ;
280+ done ( ) ;
281+
282+ // Though window.onerror is quirky, returning false generally works to suppress the error from reaching the console.
283+ return false ;
284+ }
285+ } ;
286+
287+ const fixture = TestBed . createComponent ( TestHostComponent ) ;
288+ fixture . detectChanges ( ) ;
289+ fixture . componentInstance . show = true ;
290+ fixture . detectChanges ( ) ;
291+ } ) ;
267292 } ) ;
268293} ) ;
294+
295+ function isErrorEvent ( event : Event | string ) : event is ErrorEvent {
296+ return ( < ErrorEvent > event ) . error !== undefined ;
297+ }
0 commit comments