• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals
2'use strict';
3
4const common = require('../common');
5const assert = require('assert');
6
7const {
8  PromisePrototypeThen,
9  SafePromiseAll,
10  SafePromiseAllReturnArrayLike,
11  SafePromiseAllReturnVoid,
12  SafePromiseAllSettled,
13  SafePromiseAllSettledReturnVoid,
14  SafePromiseAny,
15  SafePromisePrototypeFinally,
16  SafePromiseRace,
17} = require('internal/test/binding').primordials;
18
19Array.prototype[Symbol.iterator] = common.mustNotCall('%Array.prototype%[@@iterator]');
20Promise.all = common.mustNotCall('%Promise%.all');
21Promise.allSettled = common.mustNotCall('%Promise%.allSettled');
22Promise.any = common.mustNotCall('%Promise%.any');
23Promise.race = common.mustNotCall('%Promise%.race');
24
25Object.defineProperties(Promise.prototype, {
26  catch: {
27    set: common.mustNotCall('set %Promise.prototype%.catch'),
28    get: common.mustNotCall('get %Promise.prototype%.catch'),
29  },
30  finally: {
31    set: common.mustNotCall('set %Promise.prototype%.finally'),
32    get: common.mustNotCall('get %Promise.prototype%.finally'),
33  },
34  then: {
35    set: common.mustNotCall('set %Promise.prototype%.then'),
36    get: common.mustNotCall('get %Promise.prototype%.then'),
37  },
38});
39Object.defineProperties(Array.prototype, {
40  then: {
41    configurable: true,
42    set: common.mustNotCall('set %Array.prototype%.then'),
43    get: common.mustNotCall('get %Array.prototype%.then'),
44  },
45});
46Object.defineProperties(Object.prototype, {
47  then: {
48    set: common.mustNotCall('set %Object.prototype%.then'),
49    get: common.mustNotCall('get %Object.prototype%.then'),
50  },
51});
52
53assertIsPromise(PromisePrototypeThen(test(), common.mustCall()));
54assertIsPromise(SafePromisePrototypeFinally(test(), common.mustCall()));
55
56assertIsPromise(SafePromiseAllReturnArrayLike([test()]));
57assertIsPromise(SafePromiseAllReturnVoid([test()]));
58assertIsPromise(SafePromiseAny([test()]));
59assertIsPromise(SafePromiseRace([test()]));
60
61assertIsPromise(SafePromiseAllReturnArrayLike([]));
62assertIsPromise(SafePromiseAllReturnVoid([]));
63
64{
65  const val1 = Symbol();
66  const val2 = Symbol();
67  PromisePrototypeThen(
68    SafePromiseAllReturnArrayLike([Promise.resolve(val1), { then(resolve) { resolve(val2); } }]),
69    common.mustCall((val) => {
70      assert.strictEqual(Array.isArray(val), true);
71      const expected = [val1, val2];
72      assert.deepStrictEqual(val.length, expected.length);
73      assert.strictEqual(val[0], expected[0]);
74      assert.strictEqual(val[1], expected[1]);
75    })
76  );
77}
78
79{
80  // Never settling promises should not block the resulting promise to be rejected:
81  const error = new Error();
82  PromisePrototypeThen(
83    SafePromiseAllReturnArrayLike([new Promise(() => {}), Promise.reject(error)]),
84    common.mustNotCall('Should have rejected'),
85    common.mustCall((err) => {
86      assert.strictEqual(err, error);
87    })
88  );
89  PromisePrototypeThen(
90    SafePromiseAllReturnVoid([new Promise(() => {}), Promise.reject(error)]),
91    common.mustNotCall('Should have rejected'),
92    common.mustCall((err) => {
93      assert.strictEqual(err, error);
94    })
95  );
96}
97
98Object.defineProperties(Array.prototype, {
99  // %Promise.all% and %Promise.allSettled% are depending on the value of
100  // `%Array.prototype%.then`.
101  then: {
102    __proto__: undefined,
103    value: undefined,
104  },
105});
106
107assertIsPromise(SafePromiseAll([test()]));
108assertIsPromise(SafePromiseAllSettled([test()]));
109assertIsPromise(SafePromiseAllSettledReturnVoid([test()]));
110
111assertIsPromise(SafePromiseAll([]));
112assertIsPromise(SafePromiseAllSettled([]));
113assertIsPromise(SafePromiseAllSettledReturnVoid([]));
114
115async function test() {
116  const catchFn = common.mustCall();
117  const finallyFn = common.mustCall();
118
119  try {
120    await Promise.reject();
121  } catch {
122    catchFn();
123  } finally {
124    finallyFn();
125  }
126}
127
128function assertIsPromise(promise) {
129  // Make sure the returned promise is a genuine %Promise% object and not a
130  // subclass instance.
131  assert.strictEqual(Object.getPrototypeOf(promise), Promise.prototype);
132  PromisePrototypeThen(promise, common.mustCall());
133}
134