| /** |
| * @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); |
| if (this[symbolState] === UNRESOLVED) { |
| // 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; |
| } |
| }; |
| }); |