• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2// Flags: --expose-internals
3const common = require('../common');
4const assert = require('assert');
5const fs = require('fs');
6const vm = require('vm');
7const { promisify } = require('util');
8const { customPromisifyArgs } = require('internal/util');
9
10const stat = promisify(fs.stat);
11
12{
13  const promise = stat(__filename);
14  assert(promise instanceof Promise);
15  promise.then(common.mustCall((value) => {
16    assert.deepStrictEqual(value, fs.statSync(__filename));
17  }));
18}
19
20{
21  const promise = stat('/dontexist');
22  promise.catch(common.mustCall((error) => {
23    assert(error.message.includes('ENOENT: no such file or directory, stat'));
24  }));
25}
26
27{
28  function fn() {}
29
30  function promisifedFn() {}
31  fn[promisify.custom] = promisifedFn;
32  assert.strictEqual(promisify(fn), promisifedFn);
33  assert.strictEqual(promisify(promisify(fn)), promisifedFn);
34}
35
36{
37  function fn() {}
38
39  function promisifiedFn() {}
40
41  // util.promisify.custom is a shared symbol which can be accessed
42  // as `Symbol.for("nodejs.util.promisify.custom")`.
43  const kCustomPromisifiedSymbol = Symbol.for('nodejs.util.promisify.custom');
44  fn[kCustomPromisifiedSymbol] = promisifiedFn;
45
46  assert.strictEqual(kCustomPromisifiedSymbol, promisify.custom);
47  assert.strictEqual(promisify(fn), promisifiedFn);
48  assert.strictEqual(promisify(promisify(fn)), promisifiedFn);
49}
50
51{
52  function fn() {}
53  fn[promisify.custom] = 42;
54  assert.throws(
55    () => promisify(fn),
56    { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }
57  );
58}
59
60{
61  const firstValue = 5;
62  const secondValue = 17;
63
64  function fn(callback) {
65    callback(null, firstValue, secondValue);
66  }
67
68  fn[customPromisifyArgs] = ['first', 'second'];
69
70  promisify(fn)().then(common.mustCall((obj) => {
71    assert.deepStrictEqual(obj, { first: firstValue, second: secondValue });
72  }));
73}
74
75{
76  const fn = vm.runInNewContext('(function() {})');
77  assert.notStrictEqual(Object.getPrototypeOf(promisify(fn)),
78                        Function.prototype);
79}
80
81{
82  function fn(callback) {
83    callback(null, 'foo', 'bar');
84  }
85  promisify(fn)().then(common.mustCall((value) => {
86    assert.deepStrictEqual(value, 'foo');
87  }));
88}
89
90{
91  function fn(callback) {
92    callback(null);
93  }
94  promisify(fn)().then(common.mustCall((value) => {
95    assert.strictEqual(value, undefined);
96  }));
97}
98
99{
100  function fn(callback) {
101    callback();
102  }
103  promisify(fn)().then(common.mustCall((value) => {
104    assert.strictEqual(value, undefined);
105  }));
106}
107
108{
109  function fn(err, val, callback) {
110    callback(err, val);
111  }
112  promisify(fn)(null, 42).then(common.mustCall((value) => {
113    assert.strictEqual(value, 42);
114  }));
115}
116
117{
118  function fn(err, val, callback) {
119    callback(err, val);
120  }
121  promisify(fn)(new Error('oops'), null).catch(common.mustCall((err) => {
122    assert.strictEqual(err.message, 'oops');
123  }));
124}
125
126{
127  function fn(err, val, callback) {
128    callback(err, val);
129  }
130
131  (async () => {
132    const value = await promisify(fn)(null, 42);
133    assert.strictEqual(value, 42);
134  })().then(common.mustCall());
135}
136
137{
138  const o = {};
139  const fn = promisify(function(cb) {
140
141    cb(null, this === o);
142  });
143
144  o.fn = fn;
145
146  o.fn().then(common.mustCall((val) => assert(val)));
147}
148
149{
150  const err = new Error('Should not have called the callback with the error.');
151  const stack = err.stack;
152
153  const fn = promisify(function(cb) {
154    cb(null);
155    cb(err);
156  });
157
158  (async () => {
159    await fn();
160    await Promise.resolve();
161    return assert.strictEqual(stack, err.stack);
162  })().then(common.mustCall());
163}
164
165{
166  function c() { }
167  const a = promisify(function() { });
168  const b = promisify(a);
169  assert.notStrictEqual(c, a);
170  assert.strictEqual(a, b);
171}
172
173{
174  let errToThrow;
175  const thrower = promisify(function(a, b, c, cb) {
176    errToThrow = new Error();
177    throw errToThrow;
178  });
179  thrower(1, 2, 3)
180    .then(assert.fail)
181    .then(assert.fail, (e) => assert.strictEqual(e, errToThrow));
182}
183
184{
185  const err = new Error();
186
187  const a = promisify((cb) => cb(err))();
188  const b = promisify(() => { throw err; })();
189
190  Promise.all([
191    a.then(assert.fail, function(e) {
192      assert.strictEqual(err, e);
193    }),
194    b.then(assert.fail, function(e) {
195      assert.strictEqual(err, e);
196    }),
197  ]);
198}
199
200[undefined, null, true, 0, 'str', {}, [], Symbol()].forEach((input) => {
201  assert.throws(
202    () => promisify(input),
203    {
204      code: 'ERR_INVALID_ARG_TYPE',
205      name: 'TypeError',
206      message: 'The "original" argument must be of type function.' +
207               common.invalidArgTypeHelper(input)
208    });
209});
210