From e608e6cfbbc9fba7c74bfef72f102a502e951e6c Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 20 Aug 2024 20:27:26 +0200 Subject: [PATCH] fix(zone.js): more robust check for promise-like objects (#57388) Fixes that Zone.js wasn't checking properly if an object is promise-like. Fixes #57385. PR Close #57388 --- packages/zone.js/lib/common/promise.ts | 2 +- packages/zone.js/test/common/Promise.spec.ts | 24 ++++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/zone.js/lib/common/promise.ts b/packages/zone.js/lib/common/promise.ts index 1bcd3d91ed5..f3d7f55480e 100644 --- a/packages/zone.js/lib/common/promise.ts +++ b/packages/zone.js/lib/common/promise.ts @@ -83,7 +83,7 @@ export function patchPromise(Zone: ZoneType): void { } function isThenable(value: any): boolean { - return value && value.then; + return value && typeof value.then === 'function'; } function forwardResolution(value: any): any { diff --git a/packages/zone.js/test/common/Promise.spec.ts b/packages/zone.js/test/common/Promise.spec.ts index 9fec6780af0..3722d8e7973 100644 --- a/packages/zone.js/test/common/Promise.spec.ts +++ b/packages/zone.js/test/common/Promise.spec.ts @@ -501,7 +501,6 @@ describe( (Promise as any) .race([Promise.reject('rejection1'), 'v1']) ['catch']((v: any) => (value = v)); - // expect(Zone.current.get('queue').length).toEqual(2); flushMicrotasks(); expect(value).toEqual('rejection1'); }); @@ -513,7 +512,6 @@ describe( (Promise as any) .race([Promise.resolve('resolution'), 'v1']) .then((v: any) => (value = v)); - // expect(Zone.current.get('queue').length).toEqual(2); flushMicrotasks(); expect(value).toEqual('resolution'); }); @@ -525,22 +523,11 @@ describe( queueZone.run(() => { let value: any = null; Promise.all([Promise.reject('rejection'), 'v1'])['catch']((v: any) => (value = v)); - // expect(Zone.current.get('queue').length).toEqual(2); flushMicrotasks(); expect(value).toEqual('rejection'); }); }); - it('should resolve the value', () => { - queueZone.run(() => { - let value: any = null; - Promise.all([Promise.resolve('resolution'), 'v1']).then((v: any) => (value = v)); - // expect(Zone.current.get('queue').length).toEqual(2); - flushMicrotasks(); - expect(value).toEqual(['resolution', 'v1']); - }); - }); - it('should resolve with the sync then operation', () => { queueZone.run(() => { let value: any = null; @@ -555,7 +542,6 @@ describe( }, }; Promise.all([p1, 'v1', p2]).then((v: any) => (value = v)); - // expect(Zone.current.get('queue').length).toEqual(2); flushMicrotasks(); expect(value).toEqual(['p1', 'v1', 'p2']); }); @@ -578,13 +564,21 @@ describe( Promise.all(generators()).then((val) => { value = val; }); - // expect(Zone.current.get('queue').length).toEqual(2); flushMicrotasks(); expect(value).toEqual([1, 2]); }); }, ), ); + + it('should handle object with a truthy `then property`', () => { + queueZone.run(() => { + let value: any = null; + Promise.all([{then: 123}]).then((v: any) => (value = v)); + flushMicrotasks(); + expect(value).toEqual([jasmine.objectContaining({then: 123})]); + }); + }); }); });