angular-cn/packages/zone.js/lib/testing/promise-testing.ts

69 lines
2.3 KiB
TypeScript
Raw Normal View History

/**
* @license
* Copyright Google LLC 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 as any)[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;
}
};
});