@@ -2,6 +2,42 @@ import Vue from 'vue'
22import { Promise } from 'es6-promise'
33
44describe ( 'Component async' , ( ) => {
5+
6+ const oldSetTimeout = window . setTimeout ;
7+ const oldClearTimeout = window . clearTimeout ;
8+
9+ // will contain pending timeouts set during the test iteration
10+ // will contain the id of the timeout as the key, and the the millisecond timeout as the value
11+ // this helps to identify the timeout that is still pending
12+ let timeoutsPending = { } ;
13+
14+ beforeEach ( function ( ) {
15+ // reset the timeouts for this iteration
16+ timeoutsPending = { } ;
17+
18+ window . setTimeout = function ( func , delay ) {
19+ let id = oldSetTimeout ( function ( ) {
20+ delete timeoutsPending [ id ] ;
21+ func ( ) ;
22+ } , delay ) ;
23+ timeoutsPending [ id ] = delay ;
24+ return id
25+ } ;
26+
27+ window . clearTimeout = function ( id ) {
28+ oldClearTimeout ( id ) ;
29+ delete timeoutsPending [ id ] ;
30+ } ;
31+ } )
32+
33+ afterEach ( function ( ) {
34+ window . setTimeout = oldSetTimeout ;
35+ window . clearTimeout = oldClearTimeout ;
36+ // after the test is complete no timeouts that have been set up during the test should still be active
37+ // compare stringified JSON for better error message containing ID and millisecond timeout
38+ expect ( JSON . stringify ( timeoutsPending ) ) . toEqual ( JSON . stringify ( { } ) )
39+ } )
40+
541 it ( 'normal' , done => {
642 const vm = new Vue ( {
743 template : '<div><test></test></div>' ,
@@ -343,6 +379,34 @@ describe('Component async', () => {
343379 } , 50 )
344380 } )
345381
382+ it ( 'should not have running timeout/loading if resolved' , done => {
383+ const vm = new Vue ( {
384+ template : `<div><test/></div>` ,
385+ components : {
386+ test : ( ) => ( {
387+ component : new Promise ( ( resolve , reject ) => {
388+ setTimeout ( ( ) => {
389+ resolve ( { template : '<div>hi</div>' } )
390+ Promise . resolve ( ) . then ( ( ) => {
391+ Vue . nextTick ( next )
392+ } )
393+ } , 10 )
394+ } ) ,
395+ loading : { template : `<div>loading</div>` } ,
396+ delay : 30 ,
397+ error : { template : `<div>error</div>` } ,
398+ timeout : 40
399+ } )
400+ }
401+ } ) . $mount ( )
402+
403+ function next ( ) {
404+ expect ( vm . $el . textContent ) . toBe ( 'hi' )
405+ // the afterEach() will ensure that the timeouts for delay and timeout have been cleared
406+ done ( )
407+ }
408+ } )
409+
346410 // #7107
347411 it ( `should work when resolving sync in sibling component's mounted hook` , done => {
348412 let resolveTwo
0 commit comments