| // Flags: --expose-internals |
| 'use strict'; |
| |
| const common = require('../common'); |
| const assert = require('assert'); |
| |
| const { |
| PromisePrototypeThen, |
| SafePromiseAll, |
| SafePromiseAllReturnArrayLike, |
| SafePromiseAllReturnVoid, |
| SafePromiseAllSettled, |
| SafePromiseAllSettledReturnVoid, |
| SafePromiseAny, |
| SafePromisePrototypeFinally, |
| SafePromiseRace, |
| } = require('internal/test/binding').primordials; |
| |
| Array.prototype[Symbol.iterator] = common.mustNotCall('%Array.prototype%[@@iterator]'); |
| Promise.all = common.mustNotCall('%Promise%.all'); |
| Promise.allSettled = common.mustNotCall('%Promise%.allSettled'); |
| Promise.any = common.mustNotCall('%Promise%.any'); |
| Promise.race = common.mustNotCall('%Promise%.race'); |
| |
| Object.defineProperties(Promise.prototype, { |
| catch: { |
| set: common.mustNotCall('set %Promise.prototype%.catch'), |
| get: common.mustNotCall('get %Promise.prototype%.catch'), |
| }, |
| finally: { |
| set: common.mustNotCall('set %Promise.prototype%.finally'), |
| get: common.mustNotCall('get %Promise.prototype%.finally'), |
| }, |
| then: { |
| set: common.mustNotCall('set %Promise.prototype%.then'), |
| get: common.mustNotCall('get %Promise.prototype%.then'), |
| }, |
| }); |
| Object.defineProperties(Array.prototype, { |
| then: { |
| configurable: true, |
| set: common.mustNotCall('set %Array.prototype%.then'), |
| get: common.mustNotCall('get %Array.prototype%.then'), |
| }, |
| }); |
| Object.defineProperties(Object.prototype, { |
| then: { |
| set: common.mustNotCall('set %Object.prototype%.then'), |
| get: common.mustNotCall('get %Object.prototype%.then'), |
| }, |
| }); |
| |
| assertIsPromise(PromisePrototypeThen(test(), common.mustCall())); |
| assertIsPromise(SafePromisePrototypeFinally(test(), common.mustCall())); |
| |
| assertIsPromise(SafePromiseAllReturnArrayLike([test()])); |
| assertIsPromise(SafePromiseAllReturnVoid([test()])); |
| assertIsPromise(SafePromiseAny([test()])); |
| assertIsPromise(SafePromiseRace([test()])); |
| |
| assertIsPromise(SafePromiseAllReturnArrayLike([])); |
| assertIsPromise(SafePromiseAllReturnVoid([])); |
| |
| { |
| const val1 = Symbol(); |
| const val2 = Symbol(); |
| PromisePrototypeThen( |
| SafePromiseAllReturnArrayLike([Promise.resolve(val1), { then(resolve) { resolve(val2); } }]), |
| common.mustCall((val) => { |
| assert.strictEqual(Array.isArray(val), true); |
| const expected = [val1, val2]; |
| assert.deepStrictEqual(val.length, expected.length); |
| assert.strictEqual(val[0], expected[0]); |
| assert.strictEqual(val[1], expected[1]); |
| }) |
| ); |
| } |
| |
| { |
| // Never settling promises should not block the resulting promise to be rejected: |
| const error = new Error(); |
| PromisePrototypeThen( |
| SafePromiseAllReturnArrayLike([new Promise(() => {}), Promise.reject(error)]), |
| common.mustNotCall('Should have rejected'), |
| common.mustCall((err) => { |
| assert.strictEqual(err, error); |
| }) |
| ); |
| PromisePrototypeThen( |
| SafePromiseAllReturnVoid([new Promise(() => {}), Promise.reject(error)]), |
| common.mustNotCall('Should have rejected'), |
| common.mustCall((err) => { |
| assert.strictEqual(err, error); |
| }) |
| ); |
| } |
| |
| Object.defineProperties(Array.prototype, { |
| // %Promise.all% and %Promise.allSettled% are depending on the value of |
| // `%Array.prototype%.then`. |
| then: { |
| __proto__: undefined, |
| value: undefined, |
| }, |
| }); |
| |
| assertIsPromise(SafePromiseAll([test()])); |
| assertIsPromise(SafePromiseAllSettled([test()])); |
| assertIsPromise(SafePromiseAllSettledReturnVoid([test()])); |
| |
| assertIsPromise(SafePromiseAll([])); |
| assertIsPromise(SafePromiseAllSettled([])); |
| assertIsPromise(SafePromiseAllSettledReturnVoid([])); |
| |
| async function test() { |
| const catchFn = common.mustCall(); |
| const finallyFn = common.mustCall(); |
| |
| try { |
| await Promise.reject(); |
| } catch { |
| catchFn(); |
| } finally { |
| finallyFn(); |
| } |
| } |
| |
| function assertIsPromise(promise) { |
| // Make sure the returned promise is a genuine %Promise% object and not a |
| // subclass instance. |
| assert.strictEqual(Object.getPrototypeOf(promise), Promise.prototype); |
| PromisePrototypeThen(promise, common.mustCall()); |
| } |