• 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.mustCall((err, dirents) => {
71  assert.ifError(err);
72  assertDirents(dirents);
73}));
74
75(async () => {
76  const dirents = await fs.promises.readdir(readdirDir, {
77    withFileTypes: true
78  });
79  assertDirents(dirents);
80})();
81
82// Check for correct types when the binding returns unknowns
83const UNKNOWN = constants.UV_DIRENT_UNKNOWN;
84const oldReaddir = binding.readdir;
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.mustCall((err, dirents) => {
107  assert.ifError(err);
108  assertDirents(dirents);
109}));
110
111// Dirent types
112for (const method of typeMethods) {
113  const dirent = new fs.Dirent('foo', types[method]);
114  for (const testMethod of typeMethods) {
115    assert.strictEqual(dirent[testMethod](), testMethod === method);
116  }
117}
118