• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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