| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Promise for async/fakeAsync zoneSpec test | 
					
						
							|  |  |  |  * can support async operation which not supported by zone.js | 
					
						
							|  |  |  |  * such as | 
					
						
							|  |  |  |  * it ('test jsonp in AsyncZone', async() => { | 
					
						
							|  |  |  |  *   new Promise(res => { | 
					
						
							|  |  |  |  *     jsonp(url, (data) => { | 
					
						
							|  |  |  |  *       // success callback
 | 
					
						
							|  |  |  |  *       res(data); | 
					
						
							|  |  |  |  *     }); | 
					
						
							|  |  |  |  *   }).then((jsonpResult) => { | 
					
						
							|  |  |  |  *     // get jsonp result.
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     // user will expect AsyncZoneSpec wait for
 | 
					
						
							|  |  |  |  *     // then, but because jsonp is not zone aware
 | 
					
						
							|  |  |  |  *     // AsyncZone will finish before then is called.
 | 
					
						
							|  |  |  |  *   }); | 
					
						
							|  |  |  |  * }); | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | Zone.__load_patch('promisefortest', (global: any, Zone: ZoneType, api: _ZonePrivate) => { | 
					
						
							|  |  |  |   const symbolState: string = api.symbol('state'); | 
					
						
							|  |  |  |   const UNRESOLVED: null = null; | 
					
						
							|  |  |  |   const symbolParentUnresolved = api.symbol('parentUnresolved'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // patch Promise.prototype.then to keep an internal
 | 
					
						
							|  |  |  |   // number for tracking unresolved chained promise
 | 
					
						
							|  |  |  |   // we will decrease this number when the parent promise
 | 
					
						
							|  |  |  |   // being resolved/rejected and chained promise was
 | 
					
						
							|  |  |  |   // scheduled as a microTask.
 | 
					
						
							|  |  |  |   // so we can know such kind of chained promise still
 | 
					
						
							|  |  |  |   // not resolved in AsyncTestZone
 | 
					
						
							|  |  |  |   (Promise as any)[api.symbol('patchPromiseForTest')] = function patchPromiseForTest() { | 
					
						
							|  |  |  |     let oriThen = (Promise as any)[Zone.__symbol__('ZonePromiseThen')]; | 
					
						
							|  |  |  |     if (oriThen) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     oriThen = (Promise as any)[Zone.__symbol__('ZonePromiseThen')] = Promise.prototype.then; | 
					
						
							|  |  |  |     Promise.prototype.then = function() { | 
					
						
							|  |  |  |       const chained = oriThen.apply(this, arguments); | 
					
						
							| 
									
										
										
										
											2019-06-26 10:33:02 +02:00
										 |  |  |       if ((this as any)[symbolState] === UNRESOLVED) { | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         // parent promise is unresolved.
 | 
					
						
							|  |  |  |         const asyncTestZoneSpec = Zone.current.get('AsyncTestZoneSpec'); | 
					
						
							|  |  |  |         if (asyncTestZoneSpec) { | 
					
						
							|  |  |  |           asyncTestZoneSpec.unresolvedChainedPromiseCount++; | 
					
						
							|  |  |  |           chained[symbolParentUnresolved] = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return chained; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   (Promise as any)[api.symbol('unPatchPromiseForTest')] = function unpatchPromiseForTest() { | 
					
						
							|  |  |  |     // restore origin then
 | 
					
						
							|  |  |  |     const oriThen = (Promise as any)[Zone.__symbol__('ZonePromiseThen')]; | 
					
						
							|  |  |  |     if (oriThen) { | 
					
						
							|  |  |  |       Promise.prototype.then = oriThen; | 
					
						
							|  |  |  |       (Promise as any)[Zone.__symbol__('ZonePromiseThen')] = undefined; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2019-06-26 10:33:02 +02:00
										 |  |  | }); |