11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci// Flags: --expose-internals
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst fs = require('fs');
61cb0ef41Sopenharmony_ciconst vm = require('vm');
71cb0ef41Sopenharmony_ciconst { promisify } = require('util');
81cb0ef41Sopenharmony_ciconst { customPromisifyArgs } = require('internal/util');
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciconst stat = promisify(fs.stat);
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci{
131cb0ef41Sopenharmony_ci  const promise = stat(__filename);
141cb0ef41Sopenharmony_ci  assert(promise instanceof Promise);
151cb0ef41Sopenharmony_ci  promise.then(common.mustCall((value) => {
161cb0ef41Sopenharmony_ci    assert.deepStrictEqual(value, fs.statSync(__filename));
171cb0ef41Sopenharmony_ci  }));
181cb0ef41Sopenharmony_ci}
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci{
211cb0ef41Sopenharmony_ci  const promise = stat('/dontexist');
221cb0ef41Sopenharmony_ci  promise.catch(common.mustCall((error) => {
231cb0ef41Sopenharmony_ci    assert(error.message.includes('ENOENT: no such file or directory, stat'));
241cb0ef41Sopenharmony_ci  }));
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci{
281cb0ef41Sopenharmony_ci  function fn() {}
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  function promisifedFn() {}
311cb0ef41Sopenharmony_ci  fn[promisify.custom] = promisifedFn;
321cb0ef41Sopenharmony_ci  assert.strictEqual(promisify(fn), promisifedFn);
331cb0ef41Sopenharmony_ci  assert.strictEqual(promisify(promisify(fn)), promisifedFn);
341cb0ef41Sopenharmony_ci}
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci{
371cb0ef41Sopenharmony_ci  function fn() {}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  function promisifiedFn() {}
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  // util.promisify.custom is a shared symbol which can be accessed
421cb0ef41Sopenharmony_ci  // as `Symbol.for("nodejs.util.promisify.custom")`.
431cb0ef41Sopenharmony_ci  const kCustomPromisifiedSymbol = Symbol.for('nodejs.util.promisify.custom');
441cb0ef41Sopenharmony_ci  fn[kCustomPromisifiedSymbol] = promisifiedFn;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  assert.strictEqual(kCustomPromisifiedSymbol, promisify.custom);
471cb0ef41Sopenharmony_ci  assert.strictEqual(promisify(fn), promisifiedFn);
481cb0ef41Sopenharmony_ci  assert.strictEqual(promisify(promisify(fn)), promisifiedFn);
491cb0ef41Sopenharmony_ci}
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci{
521cb0ef41Sopenharmony_ci  function fn() {}
531cb0ef41Sopenharmony_ci  fn[promisify.custom] = 42;
541cb0ef41Sopenharmony_ci  assert.throws(
551cb0ef41Sopenharmony_ci    () => promisify(fn),
561cb0ef41Sopenharmony_ci    { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }
571cb0ef41Sopenharmony_ci  );
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci{
611cb0ef41Sopenharmony_ci  const firstValue = 5;
621cb0ef41Sopenharmony_ci  const secondValue = 17;
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  function fn(callback) {
651cb0ef41Sopenharmony_ci    callback(null, firstValue, secondValue);
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  fn[customPromisifyArgs] = ['first', 'second'];
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  promisify(fn)().then(common.mustCall((obj) => {
711cb0ef41Sopenharmony_ci    assert.deepStrictEqual(obj, { first: firstValue, second: secondValue });
721cb0ef41Sopenharmony_ci  }));
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci{
761cb0ef41Sopenharmony_ci  const fn = vm.runInNewContext('(function() {})');
771cb0ef41Sopenharmony_ci  assert.notStrictEqual(Object.getPrototypeOf(promisify(fn)),
781cb0ef41Sopenharmony_ci                        Function.prototype);
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci{
821cb0ef41Sopenharmony_ci  function fn(callback) {
831cb0ef41Sopenharmony_ci    callback(null, 'foo', 'bar');
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci  promisify(fn)().then(common.mustCall((value) => {
861cb0ef41Sopenharmony_ci    assert.strictEqual(value, 'foo');
871cb0ef41Sopenharmony_ci  }));
881cb0ef41Sopenharmony_ci}
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci{
911cb0ef41Sopenharmony_ci  function fn(callback) {
921cb0ef41Sopenharmony_ci    callback(null);
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci  promisify(fn)().then(common.mustCall((value) => {
951cb0ef41Sopenharmony_ci    assert.strictEqual(value, undefined);
961cb0ef41Sopenharmony_ci  }));
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci{
1001cb0ef41Sopenharmony_ci  function fn(callback) {
1011cb0ef41Sopenharmony_ci    callback();
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci  promisify(fn)().then(common.mustCall((value) => {
1041cb0ef41Sopenharmony_ci    assert.strictEqual(value, undefined);
1051cb0ef41Sopenharmony_ci  }));
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci{
1091cb0ef41Sopenharmony_ci  function fn(err, val, callback) {
1101cb0ef41Sopenharmony_ci    callback(err, val);
1111cb0ef41Sopenharmony_ci  }
1121cb0ef41Sopenharmony_ci  promisify(fn)(null, 42).then(common.mustCall((value) => {
1131cb0ef41Sopenharmony_ci    assert.strictEqual(value, 42);
1141cb0ef41Sopenharmony_ci  }));
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci{
1181cb0ef41Sopenharmony_ci  function fn(err, val, callback) {
1191cb0ef41Sopenharmony_ci    callback(err, val);
1201cb0ef41Sopenharmony_ci  }
1211cb0ef41Sopenharmony_ci  promisify(fn)(new Error('oops'), null).catch(common.mustCall((err) => {
1221cb0ef41Sopenharmony_ci    assert.strictEqual(err.message, 'oops');
1231cb0ef41Sopenharmony_ci  }));
1241cb0ef41Sopenharmony_ci}
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci{
1271cb0ef41Sopenharmony_ci  function fn(err, val, callback) {
1281cb0ef41Sopenharmony_ci    callback(err, val);
1291cb0ef41Sopenharmony_ci  }
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  (async () => {
1321cb0ef41Sopenharmony_ci    const value = await promisify(fn)(null, 42);
1331cb0ef41Sopenharmony_ci    assert.strictEqual(value, 42);
1341cb0ef41Sopenharmony_ci  })().then(common.mustCall());
1351cb0ef41Sopenharmony_ci}
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci{
1381cb0ef41Sopenharmony_ci  const o = {};
1391cb0ef41Sopenharmony_ci  const fn = promisify(function(cb) {
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci    cb(null, this === o);
1421cb0ef41Sopenharmony_ci  });
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci  o.fn = fn;
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  o.fn().then(common.mustCall((val) => assert(val)));
1471cb0ef41Sopenharmony_ci}
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci{
1501cb0ef41Sopenharmony_ci  const err = new Error('Should not have called the callback with the error.');
1511cb0ef41Sopenharmony_ci  const stack = err.stack;
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  const fn = promisify(function(cb) {
1541cb0ef41Sopenharmony_ci    cb(null);
1551cb0ef41Sopenharmony_ci    cb(err);
1561cb0ef41Sopenharmony_ci  });
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  (async () => {
1591cb0ef41Sopenharmony_ci    await fn();
1601cb0ef41Sopenharmony_ci    await Promise.resolve();
1611cb0ef41Sopenharmony_ci    return assert.strictEqual(stack, err.stack);
1621cb0ef41Sopenharmony_ci  })().then(common.mustCall());
1631cb0ef41Sopenharmony_ci}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci{
1661cb0ef41Sopenharmony_ci  function c() { }
1671cb0ef41Sopenharmony_ci  const a = promisify(function() { });
1681cb0ef41Sopenharmony_ci  const b = promisify(a);
1691cb0ef41Sopenharmony_ci  assert.notStrictEqual(c, a);
1701cb0ef41Sopenharmony_ci  assert.strictEqual(a, b);
1711cb0ef41Sopenharmony_ci}
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci{
1741cb0ef41Sopenharmony_ci  let errToThrow;
1751cb0ef41Sopenharmony_ci  const thrower = promisify(function(a, b, c, cb) {
1761cb0ef41Sopenharmony_ci    errToThrow = new Error();
1771cb0ef41Sopenharmony_ci    throw errToThrow;
1781cb0ef41Sopenharmony_ci  });
1791cb0ef41Sopenharmony_ci  thrower(1, 2, 3)
1801cb0ef41Sopenharmony_ci    .then(assert.fail)
1811cb0ef41Sopenharmony_ci    .then(assert.fail, (e) => assert.strictEqual(e, errToThrow));
1821cb0ef41Sopenharmony_ci}
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci{
1851cb0ef41Sopenharmony_ci  const err = new Error();
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  const a = promisify((cb) => cb(err))();
1881cb0ef41Sopenharmony_ci  const b = promisify(() => { throw err; })();
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  Promise.all([
1911cb0ef41Sopenharmony_ci    a.then(assert.fail, function(e) {
1921cb0ef41Sopenharmony_ci      assert.strictEqual(err, e);
1931cb0ef41Sopenharmony_ci    }),
1941cb0ef41Sopenharmony_ci    b.then(assert.fail, function(e) {
1951cb0ef41Sopenharmony_ci      assert.strictEqual(err, e);
1961cb0ef41Sopenharmony_ci    }),
1971cb0ef41Sopenharmony_ci  ]);
1981cb0ef41Sopenharmony_ci}
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci[undefined, null, true, 0, 'str', {}, [], Symbol()].forEach((input) => {
2011cb0ef41Sopenharmony_ci  assert.throws(
2021cb0ef41Sopenharmony_ci    () => promisify(input),
2031cb0ef41Sopenharmony_ci    {
2041cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
2051cb0ef41Sopenharmony_ci      name: 'TypeError',
2061cb0ef41Sopenharmony_ci      message: 'The "original" argument must be of type function.' +
2071cb0ef41Sopenharmony_ci               common.invalidArgTypeHelper(input)
2081cb0ef41Sopenharmony_ci    });
2091cb0ef41Sopenharmony_ci});
210