• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const fs = require('fs');
6const pathModule = require('path');
7const tmpdir = require('../common/tmpdir');
8
9const readdirDir = tmpdir.path;
10
11const fileStructure = [
12  [ 'a', [ 'foo', 'bar' ] ],
13  [ 'b', [ 'foo', 'bar' ] ],
14  [ 'c', [ 'foo', 'bar' ] ],
15  [ 'd', [ 'foo', 'bar' ] ],
16  [ 'e', [ 'foo', 'bar' ] ],
17  [ 'f', [ 'foo', 'bar' ] ],
18  [ 'g', [ 'foo', 'bar' ] ],
19  [ 'h', [ 'foo', 'bar' ] ],
20  [ 'i', [ 'foo', 'bar' ] ],
21  [ 'j', [ 'foo', 'bar' ] ],
22  [ 'k', [ 'foo', 'bar' ] ],
23  [ 'l', [ 'foo', 'bar' ] ],
24  [ 'm', [ 'foo', 'bar' ] ],
25  [ 'n', [ 'foo', 'bar' ] ],
26  [ 'o', [ 'foo', 'bar' ] ],
27  [ 'p', [ 'foo', 'bar' ] ],
28  [ 'q', [ 'foo', 'bar' ] ],
29  [ 'r', [ 'foo', 'bar' ] ],
30  [ 's', [ 'foo', 'bar' ] ],
31  [ 't', [ 'foo', 'bar' ] ],
32  [ 'u', [ 'foo', 'bar' ] ],
33  [ 'v', [ 'foo', 'bar' ] ],
34  [ 'w', [ 'foo', 'bar' ] ],
35  [ 'x', [ 'foo', 'bar' ] ],
36  [ 'y', [ 'foo', 'bar' ] ],
37  [ 'z', [ 'foo', 'bar' ] ],
38  [ 'aa', [ 'foo', 'bar' ] ],
39  [ 'bb', [ 'foo', 'bar' ] ],
40  [ 'cc', [ 'foo', 'bar' ] ],
41  [ 'dd', [ 'foo', 'bar' ] ],
42  [ 'ee', [ 'foo', 'bar' ] ],
43  [ 'ff', [ 'foo', 'bar' ] ],
44  [ 'gg', [ 'foo', 'bar' ] ],
45  [ 'hh', [ 'foo', 'bar' ] ],
46  [ 'ii', [ 'foo', 'bar' ] ],
47  [ 'jj', [ 'foo', 'bar' ] ],
48  [ 'kk', [ 'foo', 'bar' ] ],
49  [ 'll', [ 'foo', 'bar' ] ],
50  [ 'mm', [ 'foo', 'bar' ] ],
51  [ 'nn', [ 'foo', 'bar' ] ],
52  [ 'oo', [ 'foo', 'bar' ] ],
53  [ 'pp', [ 'foo', 'bar' ] ],
54  [ 'qq', [ 'foo', 'bar' ] ],
55  [ 'rr', [ 'foo', 'bar' ] ],
56  [ 'ss', [ 'foo', 'bar' ] ],
57  [ 'tt', [ 'foo', 'bar' ] ],
58  [ 'uu', [ 'foo', 'bar' ] ],
59  [ 'vv', [ 'foo', 'bar' ] ],
60  [ 'ww', [ 'foo', 'bar' ] ],
61  [ 'xx', [ 'foo', 'bar' ] ],
62  [ 'yy', [ 'foo', 'bar' ] ],
63  [ 'zz', [ 'foo', 'bar' ] ],
64  [ 'abc', [ ['def', [ 'foo', 'bar' ] ], ['ghi', [ 'foo', 'bar' ] ] ] ],
65];
66
67function createFiles(path, fileStructure) {
68  for (const fileOrDir of fileStructure) {
69    if (typeof fileOrDir === 'string') {
70      fs.writeFileSync(pathModule.join(path, fileOrDir), '');
71    } else {
72      const dirPath = pathModule.join(path, fileOrDir[0]);
73      fs.mkdirSync(dirPath);
74      createFiles(dirPath, fileOrDir[1]);
75    }
76  }
77}
78
79// Make sure tmp directory is clean
80tmpdir.refresh();
81
82createFiles(readdirDir, fileStructure);
83const symlinksRootPath = pathModule.join(readdirDir, 'symlinks');
84const symlinkTargetFile = pathModule.join(symlinksRootPath, 'symlink-target-file');
85const symlinkTargetDir = pathModule.join(symlinksRootPath, 'symlink-target-dir');
86fs.mkdirSync(symlinksRootPath);
87fs.writeFileSync(symlinkTargetFile, '');
88fs.mkdirSync(symlinkTargetDir);
89fs.symlinkSync(symlinkTargetFile, pathModule.join(symlinksRootPath, 'symlink-src-file'));
90fs.symlinkSync(symlinkTargetDir, pathModule.join(symlinksRootPath, 'symlink-src-dir'));
91
92const expected = [
93  'a', 'a/bar', 'a/foo', 'aa', 'aa/bar', 'aa/foo',
94  'abc', 'abc/def', 'abc/def/bar', 'abc/def/foo', 'abc/ghi', 'abc/ghi/bar', 'abc/ghi/foo',
95  'b', 'b/bar', 'b/foo', 'bb', 'bb/bar', 'bb/foo',
96  'c', 'c/bar', 'c/foo', 'cc', 'cc/bar', 'cc/foo',
97  'd', 'd/bar', 'd/foo', 'dd', 'dd/bar', 'dd/foo',
98  'e', 'e/bar', 'e/foo', 'ee', 'ee/bar', 'ee/foo',
99  'f', 'f/bar', 'f/foo', 'ff', 'ff/bar', 'ff/foo',
100  'g', 'g/bar', 'g/foo', 'gg', 'gg/bar', 'gg/foo',
101  'h', 'h/bar', 'h/foo', 'hh', 'hh/bar', 'hh/foo',
102  'i', 'i/bar', 'i/foo', 'ii', 'ii/bar', 'ii/foo',
103  'j', 'j/bar', 'j/foo', 'jj', 'jj/bar', 'jj/foo',
104  'k', 'k/bar', 'k/foo', 'kk', 'kk/bar', 'kk/foo',
105  'l', 'l/bar', 'l/foo', 'll', 'll/bar', 'll/foo',
106  'm', 'm/bar', 'm/foo', 'mm', 'mm/bar', 'mm/foo',
107  'n', 'n/bar', 'n/foo', 'nn', 'nn/bar', 'nn/foo',
108  'o', 'o/bar', 'o/foo', 'oo', 'oo/bar', 'oo/foo',
109  'p', 'p/bar', 'p/foo', 'pp', 'pp/bar', 'pp/foo',
110  'q', 'q/bar', 'q/foo', 'qq', 'qq/bar', 'qq/foo',
111  'r', 'r/bar', 'r/foo', 'rr', 'rr/bar', 'rr/foo',
112  's', 's/bar', 's/foo', 'ss', 'ss/bar', 'ss/foo',
113  'symlinks', 'symlinks/symlink-src-dir', 'symlinks/symlink-src-file',
114  'symlinks/symlink-target-dir', 'symlinks/symlink-target-file',
115  't', 't/bar', 't/foo', 'tt', 'tt/bar', 'tt/foo',
116  'u', 'u/bar', 'u/foo', 'uu', 'uu/bar', 'uu/foo',
117  'v', 'v/bar', 'v/foo', 'vv', 'vv/bar', 'vv/foo',
118  'w', 'w/bar', 'w/foo', 'ww', 'ww/bar', 'ww/foo',
119  'x', 'x/bar', 'x/foo', 'xx', 'xx/bar', 'xx/foo',
120  'y', 'y/bar', 'y/foo', 'yy', 'yy/bar', 'yy/foo',
121  'z', 'z/bar', 'z/foo', 'zz', 'zz/bar', 'zz/foo',
122];
123
124// Normalize paths once for non POSIX platforms
125for (let i = 0; i < expected.length; i++) {
126  expected[i] = pathModule.normalize(expected[i]);
127}
128
129function getDirentPath(dirent) {
130  return pathModule.relative(readdirDir, pathModule.join(dirent.path, dirent.name));
131}
132
133function assertDirents(dirents) {
134  assert.strictEqual(dirents.length, expected.length);
135  dirents.sort((a, b) => (getDirentPath(a) < getDirentPath(b) ? -1 : 1));
136  for (const [i, dirent] of dirents.entries()) {
137    assert(dirent instanceof fs.Dirent);
138    assert.notStrictEqual(dirent.name, undefined);
139    assert.strictEqual(getDirentPath(dirent), expected[i]);
140  }
141}
142
143// readdirSync
144
145// readdirSync { recursive }
146{
147  const result = fs.readdirSync(readdirDir, { recursive: true });
148  assert.deepStrictEqual(result.sort(), expected);
149}
150
151// readdirSync { recursive, withFileTypes }
152{
153  const result = fs.readdirSync(readdirDir, { recursive: true, withFileTypes: true });
154  assertDirents(result);
155}
156
157// readdir
158
159// readdir { recursive } callback
160{
161  fs.readdir(readdirDir, { recursive: true },
162             common.mustSucceed((result) => {
163               assert.deepStrictEqual(result.sort(), expected);
164             }));
165}
166
167// Readdir { recursive, withFileTypes } callback
168{
169  fs.readdir(readdirDir, { recursive: true, withFileTypes: true },
170             common.mustSucceed((result) => {
171               assertDirents(result);
172             }));
173}
174
175// fs.promises.readdir
176
177// fs.promises.readdir { recursive }
178{
179  async function test() {
180    const result = await fs.promises.readdir(readdirDir, { recursive: true });
181    assert.deepStrictEqual(result.sort(), expected);
182  }
183
184  test().then(common.mustCall());
185}
186
187// fs.promises.readdir { recursive, withFileTypes }
188{
189  async function test() {
190    const result = await fs.promises.readdir(readdirDir, { recursive: true, withFileTypes: true });
191    assertDirents(result);
192  }
193
194  test().then(common.mustCall());
195}
196