1// Flags: --expose-internals 2'use strict'; 3 4const common = require('../common'); 5const assert = require('assert'); 6const fs = require('fs'); 7 8const tmpdir = require('../common/tmpdir'); 9 10const { internalBinding } = require('internal/test/binding'); 11const binding = internalBinding('fs'); 12 13const readdirDir = tmpdir.path; 14const files = ['empty', 'files', 'for', 'just', 'testing']; 15const constants = require('fs').constants; 16const types = { 17 isDirectory: constants.UV_DIRENT_DIR, 18 isFile: constants.UV_DIRENT_FILE, 19 isBlockDevice: constants.UV_DIRENT_BLOCK, 20 isCharacterDevice: constants.UV_DIRENT_CHAR, 21 isSymbolicLink: constants.UV_DIRENT_LINK, 22 isFIFO: constants.UV_DIRENT_FIFO, 23 isSocket: constants.UV_DIRENT_SOCKET 24}; 25const typeMethods = Object.keys(types); 26 27// Make sure tmp directory is clean 28tmpdir.refresh(); 29 30// Create the necessary files 31files.forEach(function(currentFile) { 32 fs.closeSync(fs.openSync(`${readdirDir}/${currentFile}`, 'w')); 33}); 34 35 36function assertDirents(dirents) { 37 assert.strictEqual(files.length, dirents.length); 38 for (const [i, dirent] of dirents.entries()) { 39 assert(dirent instanceof fs.Dirent); 40 assert.strictEqual(dirent.name, files[i]); 41 assert.strictEqual(dirent.isFile(), true); 42 assert.strictEqual(dirent.isDirectory(), false); 43 assert.strictEqual(dirent.isSocket(), false); 44 assert.strictEqual(dirent.isBlockDevice(), false); 45 assert.strictEqual(dirent.isCharacterDevice(), false); 46 assert.strictEqual(dirent.isFIFO(), false); 47 assert.strictEqual(dirent.isSymbolicLink(), false); 48 } 49} 50 51// Check the readdir Sync version 52assertDirents(fs.readdirSync(readdirDir, { withFileTypes: true })); 53 54fs.readdir(__filename, { 55 withFileTypes: true 56}, common.mustCall((err) => { 57 assert.throws( 58 () => { throw err; }, 59 { 60 code: 'ENOTDIR', 61 name: 'Error', 62 message: `ENOTDIR: not a directory, scandir '${__filename}'` 63 } 64 ); 65})); 66 67// Check the readdir async version 68fs.readdir(readdirDir, { 69 withFileTypes: true 70}, common.mustSucceed((dirents) => { 71 assertDirents(dirents); 72})); 73 74(async () => { 75 const dirents = await fs.promises.readdir(readdirDir, { 76 withFileTypes: true 77 }); 78 assertDirents(dirents); 79})().then(common.mustCall()); 80 81// Check for correct types when the binding returns unknowns 82const UNKNOWN = constants.UV_DIRENT_UNKNOWN; 83const oldReaddir = binding.readdir; 84process.on('beforeExit', () => { binding.readdir = oldReaddir; }); 85binding.readdir = common.mustCall((path, encoding, types, req, ctx) => { 86 if (req) { 87 const oldCb = req.oncomplete; 88 req.oncomplete = (err, results) => { 89 if (err) { 90 oldCb(err); 91 return; 92 } 93 results[1] = results[1].map(() => UNKNOWN); 94 oldCb(null, results); 95 }; 96 oldReaddir(path, encoding, types, req); 97 } else { 98 const results = oldReaddir(path, encoding, types, req, ctx); 99 results[1] = results[1].map(() => UNKNOWN); 100 return results; 101 } 102}, 2); 103assertDirents(fs.readdirSync(readdirDir, { withFileTypes: true })); 104fs.readdir(readdirDir, { 105 withFileTypes: true 106}, common.mustSucceed((dirents) => { 107 assertDirents(dirents); 108})); 109 110// Dirent types 111for (const method of typeMethods) { 112 const dirent = new fs.Dirent('foo', types[method]); 113 for (const testMethod of typeMethods) { 114 assert.strictEqual(dirent[testMethod](), testMethod === method); 115 } 116} 117