promise-testing.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /**
  2. * @license
  3. * Copyright Google Inc. All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. /**
  9. * Promise for async/fakeAsync zoneSpec test
  10. * can support async operation which not supported by zone.js
  11. * such as
  12. * it ('test jsonp in AsyncZone', async() => {
  13. * new Promise(res => {
  14. * jsonp(url, (data) => {
  15. * // success callback
  16. * res(data);
  17. * });
  18. * }).then((jsonpResult) => {
  19. * // get jsonp result.
  20. *
  21. * // user will expect AsyncZoneSpec wait for
  22. * // then, but because jsonp is not zone aware
  23. * // AsyncZone will finish before then is called.
  24. * });
  25. * });
  26. */
  27. Zone.__load_patch('promisefortest', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
  28. const symbolState: string = api.symbol('state');
  29. const UNRESOLVED: null = null;
  30. const symbolParentUnresolved = api.symbol('parentUnresolved');
  31. // patch Promise.prototype.then to keep an internal
  32. // number for tracking unresolved chained promise
  33. // we will decrease this number when the parent promise
  34. // being resolved/rejected and chained promise was
  35. // scheduled as a microTask.
  36. // so we can know such kind of chained promise still
  37. // not resolved in AsyncTestZone
  38. (Promise as any)[api.symbol('patchPromiseForTest')] = function patchPromiseForTest() {
  39. let oriThen = (Promise as any)[Zone.__symbol__('ZonePromiseThen')];
  40. if (oriThen) {
  41. return;
  42. }
  43. oriThen = (Promise as any)[Zone.__symbol__('ZonePromiseThen')] = Promise.prototype.then;
  44. Promise.prototype.then = function() {
  45. const chained = oriThen.apply(this, arguments);
  46. if (this[symbolState] === UNRESOLVED) {
  47. // parent promise is unresolved.
  48. const asyncTestZoneSpec = Zone.current.get('AsyncTestZoneSpec');
  49. if (asyncTestZoneSpec) {
  50. asyncTestZoneSpec.unresolvedChainedPromiseCount++;
  51. chained[symbolParentUnresolved] = true;
  52. }
  53. }
  54. return chained;
  55. };
  56. };
  57. (Promise as any)[api.symbol('unPatchPromiseForTest')] = function unpatchPromiseForTest() {
  58. // restore origin then
  59. const oriThen = (Promise as any)[Zone.__symbol__('ZonePromiseThen')];
  60. if (oriThen) {
  61. Promise.prototype.then = oriThen;
  62. (Promise as any)[Zone.__symbol__('ZonePromiseThen')] = undefined;
  63. }
  64. };
  65. });