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