@gjsify/fs 0.0.4 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -2
- package/lib/esm/callback.js +251 -15
- package/lib/esm/dirent.js +47 -6
- package/lib/esm/encoding.js +2 -3
- package/lib/esm/errors.js +13 -0
- package/lib/esm/file-handle.js +108 -66
- package/lib/esm/fs-watcher.js +44 -7
- package/lib/esm/index.js +140 -5
- package/lib/esm/promises.js +290 -69
- package/lib/esm/read-stream.js +82 -57
- package/lib/esm/stats.js +138 -18
- package/lib/esm/sync.js +293 -44
- package/lib/esm/write-stream.js +4 -4
- package/lib/types/callback.d.ts +233 -0
- package/lib/types/dirent.d.ts +77 -0
- package/lib/types/encoding.d.ts +6 -0
- package/lib/types/errors.d.ts +7 -0
- package/lib/types/file-handle.d.ts +367 -0
- package/lib/types/fs-watcher.d.ts +17 -0
- package/lib/types/index.d.ts +149 -0
- package/lib/types/promises.d.ts +158 -0
- package/lib/types/read-stream.d.ts +21 -0
- package/lib/types/stats.d.ts +67 -0
- package/lib/types/sync.d.ts +109 -0
- package/lib/types/types/encoding-option.d.ts +2 -0
- package/lib/types/types/file-read-options.d.ts +15 -0
- package/lib/types/types/file-read-result.d.ts +4 -0
- package/lib/types/types/flag-and-open-mode.d.ts +5 -0
- package/lib/types/types/index.d.ts +6 -0
- package/lib/types/types/open-flags.d.ts +1 -0
- package/lib/types/types/read-options.d.ts +5 -0
- package/lib/types/utils.d.ts +2 -0
- package/lib/types/write-stream.d.ts +45 -0
- package/package.json +22 -35
- package/src/callback.spec.ts +284 -30
- package/src/callback.ts +352 -39
- package/src/dirent.ts +56 -8
- package/src/encoding.ts +7 -2
- package/src/errors.spec.ts +389 -0
- package/src/errors.ts +19 -0
- package/src/extended.spec.ts +706 -0
- package/src/file-handle.spec.ts +104 -23
- package/src/file-handle.ts +147 -79
- package/src/fs-watcher.ts +55 -8
- package/src/index.ts +146 -2
- package/src/new-apis.spec.ts +505 -0
- package/src/promises.spec.ts +651 -11
- package/src/promises.ts +353 -81
- package/src/read-stream.ts +98 -74
- package/src/stat.spec.ts +22 -14
- package/src/stats.ts +176 -75
- package/src/streams.spec.ts +455 -0
- package/src/symlink.spec.ts +176 -26
- package/src/sync.spec.ts +204 -32
- package/src/sync.ts +363 -58
- package/src/test.mts +7 -2
- package/src/types/encoding-option.ts +1 -1
- package/src/types/flag-and-open-mode.ts +1 -1
- package/src/types/read-options.ts +2 -2
- package/src/utils.ts +2 -0
- package/src/write-stream.ts +9 -7
- package/tsconfig.json +23 -10
- package/tsconfig.tsbuildinfo +1 -0
- package/lib/cjs/callback.js +0 -112
- package/lib/cjs/dirent.js +0 -98
- package/lib/cjs/encoding.js +0 -34
- package/lib/cjs/file-handle.js +0 -444
- package/lib/cjs/fs-watcher.js +0 -50
- package/lib/cjs/index.js +0 -95
- package/lib/cjs/promises.js +0 -160
- package/lib/cjs/read-stream.js +0 -78
- package/lib/cjs/stats.js +0 -45
- package/lib/cjs/sync.js +0 -126
- package/lib/cjs/types/encoding-option.js +0 -0
- package/lib/cjs/types/file-read-options.js +0 -0
- package/lib/cjs/types/file-read-result.js +0 -0
- package/lib/cjs/types/flag-and-open-mode.js +0 -0
- package/lib/cjs/types/index.js +0 -6
- package/lib/cjs/types/open-flags.js +0 -0
- package/lib/cjs/types/read-options.js +0 -0
- package/lib/cjs/utils.js +0 -18
- package/lib/cjs/write-stream.js +0 -116
- package/test/watch.js +0 -1
- package/test.gjs.js +0 -35359
- package/test.gjs.js.map +0 -7
- package/test.gjs.mjs +0 -40534
- package/test.gjs.mjs.meta.json +0 -1
- package/test.node.js +0 -1479
- package/test.node.js.map +0 -7
- package/test.node.mjs +0 -710
- package/tsconfig.types.json +0 -8
package/src/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Reference: Node.js lib/fs.js
|
|
2
|
+
// Reimplemented for GJS using Gio.File
|
|
3
|
+
|
|
1
4
|
import {
|
|
2
5
|
existsSync,
|
|
3
6
|
readdirSync,
|
|
@@ -14,8 +17,18 @@ import {
|
|
|
14
17
|
realpathSync,
|
|
15
18
|
symlinkSync,
|
|
16
19
|
lstatSync,
|
|
20
|
+
renameSync,
|
|
21
|
+
copyFileSync,
|
|
22
|
+
accessSync,
|
|
23
|
+
appendFileSync,
|
|
24
|
+
readlinkSync,
|
|
25
|
+
linkSync,
|
|
26
|
+
truncateSync,
|
|
27
|
+
chmodSync,
|
|
28
|
+
chownSync,
|
|
17
29
|
} from './sync.js';
|
|
18
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
open,
|
|
19
32
|
close,
|
|
20
33
|
read,
|
|
21
34
|
write,
|
|
@@ -24,16 +37,88 @@ import { open,
|
|
|
24
37
|
readdir,
|
|
25
38
|
symlink,
|
|
26
39
|
lstat,
|
|
40
|
+
stat,
|
|
41
|
+
rename,
|
|
42
|
+
copyFile,
|
|
43
|
+
access,
|
|
44
|
+
appendFile,
|
|
45
|
+
readlink,
|
|
46
|
+
truncate,
|
|
47
|
+
chmod,
|
|
48
|
+
chown,
|
|
49
|
+
mkdir,
|
|
50
|
+
rmdir,
|
|
51
|
+
readFile,
|
|
52
|
+
writeFile,
|
|
53
|
+
unlink,
|
|
54
|
+
link,
|
|
27
55
|
} from './callback.js';
|
|
28
56
|
import FSWatcher from './fs-watcher.js';
|
|
29
57
|
import {
|
|
30
58
|
createReadStream,
|
|
31
59
|
ReadStream
|
|
32
60
|
} from './read-stream.js';
|
|
61
|
+
import {
|
|
62
|
+
createWriteStream,
|
|
63
|
+
WriteStream
|
|
64
|
+
} from './write-stream.js';
|
|
33
65
|
import * as promises from './promises.js';
|
|
66
|
+
import { Stats, BigIntStats } from './stats.js';
|
|
67
|
+
import { Dirent } from './dirent.js';
|
|
68
|
+
|
|
69
|
+
// --- fs.constants ---
|
|
70
|
+
export const constants = {
|
|
71
|
+
// File access constants
|
|
72
|
+
F_OK: 0,
|
|
73
|
+
R_OK: 4,
|
|
74
|
+
W_OK: 2,
|
|
75
|
+
X_OK: 1,
|
|
76
|
+
// File copy constants
|
|
77
|
+
COPYFILE_EXCL: 1,
|
|
78
|
+
COPYFILE_FICLONE: 2,
|
|
79
|
+
COPYFILE_FICLONE_FORCE: 4,
|
|
80
|
+
// File open constants
|
|
81
|
+
O_RDONLY: 0,
|
|
82
|
+
O_WRONLY: 1,
|
|
83
|
+
O_RDWR: 2,
|
|
84
|
+
O_CREAT: 64,
|
|
85
|
+
O_EXCL: 128,
|
|
86
|
+
O_TRUNC: 512,
|
|
87
|
+
O_APPEND: 1024,
|
|
88
|
+
O_SYNC: 1052672,
|
|
89
|
+
O_NONBLOCK: 2048,
|
|
90
|
+
O_DIRECTORY: 65536,
|
|
91
|
+
O_NOFOLLOW: 131072,
|
|
92
|
+
// File type constants
|
|
93
|
+
S_IFMT: 61440,
|
|
94
|
+
S_IFREG: 32768,
|
|
95
|
+
S_IFDIR: 16384,
|
|
96
|
+
S_IFCHR: 8192,
|
|
97
|
+
S_IFBLK: 24576,
|
|
98
|
+
S_IFIFO: 4096,
|
|
99
|
+
S_IFLNK: 40960,
|
|
100
|
+
S_IFSOCK: 49152,
|
|
101
|
+
// File mode constants
|
|
102
|
+
S_IRWXU: 448,
|
|
103
|
+
S_IRUSR: 256,
|
|
104
|
+
S_IWUSR: 128,
|
|
105
|
+
S_IXUSR: 64,
|
|
106
|
+
S_IRWXG: 56,
|
|
107
|
+
S_IRGRP: 32,
|
|
108
|
+
S_IWGRP: 16,
|
|
109
|
+
S_IXGRP: 8,
|
|
110
|
+
S_IRWXO: 7,
|
|
111
|
+
S_IROTH: 4,
|
|
112
|
+
S_IWOTH: 2,
|
|
113
|
+
S_IXOTH: 1,
|
|
114
|
+
};
|
|
34
115
|
|
|
35
116
|
export {
|
|
36
117
|
FSWatcher,
|
|
118
|
+
Stats,
|
|
119
|
+
BigIntStats,
|
|
120
|
+
Dirent,
|
|
121
|
+
// Sync API
|
|
37
122
|
existsSync,
|
|
38
123
|
readdirSync,
|
|
39
124
|
readFileSync,
|
|
@@ -48,10 +133,24 @@ export {
|
|
|
48
133
|
realpathSync,
|
|
49
134
|
symlinkSync,
|
|
50
135
|
lstatSync,
|
|
136
|
+
renameSync,
|
|
137
|
+
copyFileSync,
|
|
138
|
+
accessSync,
|
|
139
|
+
appendFileSync,
|
|
140
|
+
readlinkSync,
|
|
141
|
+
linkSync,
|
|
142
|
+
truncateSync,
|
|
143
|
+
chmodSync,
|
|
144
|
+
chownSync,
|
|
51
145
|
watch,
|
|
146
|
+
// Streams
|
|
52
147
|
createReadStream,
|
|
53
148
|
ReadStream,
|
|
149
|
+
createWriteStream,
|
|
150
|
+
WriteStream,
|
|
151
|
+
// Promises
|
|
54
152
|
promises,
|
|
153
|
+
// Callback API
|
|
55
154
|
open,
|
|
56
155
|
close,
|
|
57
156
|
read,
|
|
@@ -61,10 +160,29 @@ export {
|
|
|
61
160
|
readdir,
|
|
62
161
|
symlink,
|
|
63
162
|
lstat,
|
|
163
|
+
stat,
|
|
164
|
+
rename,
|
|
165
|
+
copyFile,
|
|
166
|
+
access,
|
|
167
|
+
appendFile,
|
|
168
|
+
readlink,
|
|
169
|
+
truncate,
|
|
170
|
+
chmod,
|
|
171
|
+
chown,
|
|
172
|
+
mkdir,
|
|
173
|
+
rmdir,
|
|
174
|
+
readFile,
|
|
175
|
+
writeFile,
|
|
176
|
+
unlink,
|
|
177
|
+
link,
|
|
64
178
|
};
|
|
65
179
|
|
|
66
180
|
export default {
|
|
67
181
|
FSWatcher,
|
|
182
|
+
Stats,
|
|
183
|
+
BigIntStats,
|
|
184
|
+
Dirent,
|
|
185
|
+
constants,
|
|
68
186
|
existsSync,
|
|
69
187
|
readdirSync,
|
|
70
188
|
readFileSync,
|
|
@@ -79,9 +197,20 @@ export default {
|
|
|
79
197
|
realpathSync,
|
|
80
198
|
symlinkSync,
|
|
81
199
|
lstatSync,
|
|
200
|
+
renameSync,
|
|
201
|
+
copyFileSync,
|
|
202
|
+
accessSync,
|
|
203
|
+
appendFileSync,
|
|
204
|
+
readlinkSync,
|
|
205
|
+
linkSync,
|
|
206
|
+
truncateSync,
|
|
207
|
+
chmodSync,
|
|
208
|
+
chownSync,
|
|
82
209
|
watch,
|
|
83
210
|
createReadStream,
|
|
84
211
|
ReadStream,
|
|
212
|
+
createWriteStream,
|
|
213
|
+
WriteStream,
|
|
85
214
|
promises,
|
|
86
215
|
open,
|
|
87
216
|
close,
|
|
@@ -92,4 +221,19 @@ export default {
|
|
|
92
221
|
readdir,
|
|
93
222
|
symlink,
|
|
94
223
|
lstat,
|
|
95
|
-
|
|
224
|
+
stat,
|
|
225
|
+
rename,
|
|
226
|
+
copyFile,
|
|
227
|
+
access,
|
|
228
|
+
appendFile,
|
|
229
|
+
readlink,
|
|
230
|
+
truncate,
|
|
231
|
+
chmod,
|
|
232
|
+
chown,
|
|
233
|
+
mkdir,
|
|
234
|
+
rmdir,
|
|
235
|
+
readFile,
|
|
236
|
+
writeFile,
|
|
237
|
+
unlink,
|
|
238
|
+
link,
|
|
239
|
+
};
|
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
// Ported from refs/node/test/parallel/test-fs-*.js
|
|
2
|
+
// Original: MIT license, Node.js contributors
|
|
3
|
+
|
|
4
|
+
import { describe, it, expect } from '@gjsify/unit';
|
|
5
|
+
import {
|
|
6
|
+
existsSync, mkdtempSync, rmdirSync, rmSync, writeFileSync, readFileSync,
|
|
7
|
+
renameSync, copyFileSync, accessSync, appendFileSync, readlinkSync,
|
|
8
|
+
symlinkSync, unlinkSync, truncateSync, createReadStream, createWriteStream,
|
|
9
|
+
constants, mkdirSync,
|
|
10
|
+
rename, copyFile, access, appendFile, readFile, writeFile,
|
|
11
|
+
} from 'node:fs';
|
|
12
|
+
import * as promises from 'node:fs/promises';
|
|
13
|
+
import { Buffer } from 'node:buffer';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
|
|
16
|
+
export default async () => {
|
|
17
|
+
|
|
18
|
+
// ==================== constants ====================
|
|
19
|
+
|
|
20
|
+
await describe('fs.constants', async () => {
|
|
21
|
+
await it('should export F_OK, R_OK, W_OK, X_OK', async () => {
|
|
22
|
+
expect(constants.F_OK).toBe(0);
|
|
23
|
+
expect(constants.R_OK).toBe(4);
|
|
24
|
+
expect(constants.W_OK).toBe(2);
|
|
25
|
+
expect(constants.X_OK).toBe(1);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
await it('should export COPYFILE_EXCL', async () => {
|
|
29
|
+
expect(constants.COPYFILE_EXCL).toBe(1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
await it('should export file type constants', async () => {
|
|
33
|
+
expect(constants.S_IFMT).toBeDefined();
|
|
34
|
+
expect(constants.S_IFREG).toBeDefined();
|
|
35
|
+
expect(constants.S_IFDIR).toBeDefined();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
await it('should export file mode constants', async () => {
|
|
39
|
+
expect(constants.S_IRUSR).toBeDefined();
|
|
40
|
+
expect(constants.S_IWUSR).toBeDefined();
|
|
41
|
+
expect(constants.S_IXUSR).toBeDefined();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// ==================== renameSync ====================
|
|
46
|
+
|
|
47
|
+
await describe('fs.renameSync', async () => {
|
|
48
|
+
await it('should rename a file', async () => {
|
|
49
|
+
const dir = mkdtempSync('fs-test-');
|
|
50
|
+
const oldPath = join(dir, 'old.txt');
|
|
51
|
+
const newPath = join(dir, 'new.txt');
|
|
52
|
+
writeFileSync(oldPath, 'content');
|
|
53
|
+
renameSync(oldPath, newPath);
|
|
54
|
+
|
|
55
|
+
expect(existsSync(newPath)).toBeTruthy();
|
|
56
|
+
expect(existsSync(oldPath)).toBeFalsy();
|
|
57
|
+
expect(String(readFileSync(newPath, 'utf-8'))).toBe('content');
|
|
58
|
+
|
|
59
|
+
rmSync(newPath);
|
|
60
|
+
rmdirSync(dir);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// ==================== rename (callback) ====================
|
|
65
|
+
|
|
66
|
+
await describe('fs.rename (callback)', async () => {
|
|
67
|
+
await it('should rename a file asynchronously', async () => {
|
|
68
|
+
const dir = mkdtempSync('fs-test-');
|
|
69
|
+
const oldPath = join(dir, 'old.txt');
|
|
70
|
+
const newPath = join(dir, 'new.txt');
|
|
71
|
+
writeFileSync(oldPath, 'data');
|
|
72
|
+
|
|
73
|
+
await new Promise<void>((resolve, reject) => {
|
|
74
|
+
rename(oldPath, newPath, (err) => {
|
|
75
|
+
if (err) reject(err);
|
|
76
|
+
else resolve();
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
expect(existsSync(newPath)).toBeTruthy();
|
|
81
|
+
expect(existsSync(oldPath)).toBeFalsy();
|
|
82
|
+
|
|
83
|
+
rmSync(newPath);
|
|
84
|
+
rmdirSync(dir);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// ==================== copyFileSync ====================
|
|
89
|
+
|
|
90
|
+
await describe('fs.copyFileSync', async () => {
|
|
91
|
+
await it('should copy a file', async () => {
|
|
92
|
+
const dir = mkdtempSync('fs-test-');
|
|
93
|
+
const src = join(dir, 'src.txt');
|
|
94
|
+
const dest = join(dir, 'dest.txt');
|
|
95
|
+
writeFileSync(src, 'copy me');
|
|
96
|
+
copyFileSync(src, dest);
|
|
97
|
+
|
|
98
|
+
expect(existsSync(dest)).toBeTruthy();
|
|
99
|
+
expect(String(readFileSync(dest, 'utf-8'))).toBe('copy me');
|
|
100
|
+
|
|
101
|
+
rmSync(src);
|
|
102
|
+
rmSync(dest);
|
|
103
|
+
rmdirSync(dir);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await it('should overwrite existing file by default', async () => {
|
|
107
|
+
const dir = mkdtempSync('fs-test-');
|
|
108
|
+
const src = join(dir, 'src.txt');
|
|
109
|
+
const dest = join(dir, 'dest.txt');
|
|
110
|
+
writeFileSync(src, 'new content');
|
|
111
|
+
writeFileSync(dest, 'old content');
|
|
112
|
+
copyFileSync(src, dest);
|
|
113
|
+
|
|
114
|
+
expect(String(readFileSync(dest, 'utf-8'))).toBe('new content');
|
|
115
|
+
|
|
116
|
+
rmSync(src);
|
|
117
|
+
rmSync(dest);
|
|
118
|
+
rmdirSync(dir);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// ==================== copyFile (callback) ====================
|
|
123
|
+
|
|
124
|
+
await describe('fs.copyFile (callback)', async () => {
|
|
125
|
+
await it('should copy a file asynchronously', async () => {
|
|
126
|
+
const dir = mkdtempSync('fs-test-');
|
|
127
|
+
const src = join(dir, 'src.txt');
|
|
128
|
+
const dest = join(dir, 'dest.txt');
|
|
129
|
+
writeFileSync(src, 'async copy');
|
|
130
|
+
|
|
131
|
+
await new Promise<void>((resolve, reject) => {
|
|
132
|
+
copyFile(src, dest, (err) => {
|
|
133
|
+
if (err) reject(err);
|
|
134
|
+
else resolve();
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
expect(existsSync(dest)).toBeTruthy();
|
|
139
|
+
|
|
140
|
+
rmSync(src);
|
|
141
|
+
rmSync(dest);
|
|
142
|
+
rmdirSync(dir);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// ==================== accessSync ====================
|
|
147
|
+
|
|
148
|
+
await describe('fs.accessSync', async () => {
|
|
149
|
+
await it('should not throw for existing file with F_OK', async () => {
|
|
150
|
+
const dir = mkdtempSync('fs-test-');
|
|
151
|
+
const file = join(dir, 'test.txt');
|
|
152
|
+
writeFileSync(file, '');
|
|
153
|
+
|
|
154
|
+
let threw = false;
|
|
155
|
+
try {
|
|
156
|
+
accessSync(file, constants.F_OK);
|
|
157
|
+
} catch {
|
|
158
|
+
threw = true;
|
|
159
|
+
}
|
|
160
|
+
expect(threw).toBeFalsy();
|
|
161
|
+
|
|
162
|
+
rmSync(file);
|
|
163
|
+
rmdirSync(dir);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await it('should throw for non-existing file', async () => {
|
|
167
|
+
let threw = false;
|
|
168
|
+
try {
|
|
169
|
+
accessSync('/nonexistent/path/file.txt');
|
|
170
|
+
} catch {
|
|
171
|
+
threw = true;
|
|
172
|
+
}
|
|
173
|
+
expect(threw).toBeTruthy();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await it('should check read permission with R_OK', async () => {
|
|
177
|
+
const dir = mkdtempSync('fs-test-');
|
|
178
|
+
const file = join(dir, 'test.txt');
|
|
179
|
+
writeFileSync(file, '');
|
|
180
|
+
|
|
181
|
+
let threw = false;
|
|
182
|
+
try {
|
|
183
|
+
accessSync(file, constants.R_OK);
|
|
184
|
+
} catch {
|
|
185
|
+
threw = true;
|
|
186
|
+
}
|
|
187
|
+
expect(threw).toBeFalsy();
|
|
188
|
+
|
|
189
|
+
rmSync(file);
|
|
190
|
+
rmdirSync(dir);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// ==================== access (callback) ====================
|
|
195
|
+
|
|
196
|
+
await describe('fs.access (callback)', async () => {
|
|
197
|
+
await it('should callback without error for existing file', async () => {
|
|
198
|
+
const dir = mkdtempSync('fs-test-');
|
|
199
|
+
const file = join(dir, 'test.txt');
|
|
200
|
+
writeFileSync(file, '');
|
|
201
|
+
|
|
202
|
+
await new Promise<void>((resolve, reject) => {
|
|
203
|
+
access(file, (err) => {
|
|
204
|
+
if (err) reject(err);
|
|
205
|
+
else resolve();
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
rmSync(file);
|
|
210
|
+
rmdirSync(dir);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await it('should callback with error for non-existing file', async () => {
|
|
214
|
+
const err = await new Promise<Error>((resolve) => {
|
|
215
|
+
access('/nonexistent/path', (e) => {
|
|
216
|
+
resolve(e as Error);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
expect(err).toBeDefined();
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// ==================== appendFileSync ====================
|
|
224
|
+
|
|
225
|
+
await describe('fs.appendFileSync', async () => {
|
|
226
|
+
await it('should append data to a file', async () => {
|
|
227
|
+
const dir = mkdtempSync('fs-test-');
|
|
228
|
+
const file = join(dir, 'append.txt');
|
|
229
|
+
writeFileSync(file, 'hello');
|
|
230
|
+
appendFileSync(file, ' world');
|
|
231
|
+
|
|
232
|
+
expect(String(readFileSync(file, 'utf-8'))).toBe('hello world');
|
|
233
|
+
|
|
234
|
+
rmSync(file);
|
|
235
|
+
rmdirSync(dir);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
await it('should create file if it does not exist', async () => {
|
|
239
|
+
const dir = mkdtempSync('fs-test-');
|
|
240
|
+
const file = join(dir, 'new.txt');
|
|
241
|
+
appendFileSync(file, 'created');
|
|
242
|
+
|
|
243
|
+
expect(existsSync(file)).toBeTruthy();
|
|
244
|
+
expect(String(readFileSync(file, 'utf-8'))).toBe('created');
|
|
245
|
+
|
|
246
|
+
rmSync(file);
|
|
247
|
+
rmdirSync(dir);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// ==================== appendFile (callback) ====================
|
|
252
|
+
|
|
253
|
+
await describe('fs.appendFile (callback)', async () => {
|
|
254
|
+
await it('should append data asynchronously', async () => {
|
|
255
|
+
const dir = mkdtempSync('fs-test-');
|
|
256
|
+
const file = join(dir, 'append.txt');
|
|
257
|
+
writeFileSync(file, 'start');
|
|
258
|
+
|
|
259
|
+
await new Promise<void>((resolve, reject) => {
|
|
260
|
+
appendFile(file, '-end', (err) => {
|
|
261
|
+
if (err) reject(err);
|
|
262
|
+
else resolve();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
expect(String(readFileSync(file, 'utf-8'))).toBe('start-end');
|
|
267
|
+
|
|
268
|
+
rmSync(file);
|
|
269
|
+
rmdirSync(dir);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// ==================== truncateSync ====================
|
|
274
|
+
|
|
275
|
+
await describe('fs.truncateSync', async () => {
|
|
276
|
+
await it('should truncate a file to 0 bytes', async () => {
|
|
277
|
+
const dir = mkdtempSync('fs-test-');
|
|
278
|
+
const file = join(dir, 'truncate.txt');
|
|
279
|
+
writeFileSync(file, 'hello world');
|
|
280
|
+
truncateSync(file);
|
|
281
|
+
|
|
282
|
+
expect(String(readFileSync(file, 'utf-8'))).toBe('');
|
|
283
|
+
|
|
284
|
+
rmSync(file);
|
|
285
|
+
rmdirSync(dir);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// ==================== readlinkSync ====================
|
|
290
|
+
|
|
291
|
+
await describe('fs.readlinkSync', async () => {
|
|
292
|
+
await it('should read symlink target', async () => {
|
|
293
|
+
const dir = mkdtempSync('fs-test-');
|
|
294
|
+
const target = join(dir, 'target.txt');
|
|
295
|
+
const link = join(dir, 'link.txt');
|
|
296
|
+
writeFileSync(target, 'data');
|
|
297
|
+
symlinkSync(target, link);
|
|
298
|
+
|
|
299
|
+
const result = readlinkSync(link);
|
|
300
|
+
expect(String(result)).toBe(target);
|
|
301
|
+
|
|
302
|
+
unlinkSync(link);
|
|
303
|
+
rmSync(target);
|
|
304
|
+
rmdirSync(dir);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// ==================== readFile / writeFile (callback) ====================
|
|
309
|
+
|
|
310
|
+
await describe('fs.readFile / fs.writeFile (callback)', async () => {
|
|
311
|
+
await it('should write and read a file', async () => {
|
|
312
|
+
const dir = mkdtempSync('fs-test-');
|
|
313
|
+
const file = join(dir, 'rw.txt');
|
|
314
|
+
|
|
315
|
+
await new Promise<void>((resolve, reject) => {
|
|
316
|
+
writeFile(file, 'callback data', (err) => {
|
|
317
|
+
if (err) reject(err);
|
|
318
|
+
else resolve();
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
const data = await new Promise<string>((resolve, reject) => {
|
|
323
|
+
readFile(file, 'utf-8', (err, data) => {
|
|
324
|
+
if (err) reject(err);
|
|
325
|
+
else resolve(String(data));
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
expect(data).toBe('callback data');
|
|
330
|
+
|
|
331
|
+
rmSync(file);
|
|
332
|
+
rmdirSync(dir);
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// ==================== createReadStream ====================
|
|
337
|
+
|
|
338
|
+
await describe('fs.createReadStream', async () => {
|
|
339
|
+
await it('should read file contents via stream', async () => {
|
|
340
|
+
const dir = mkdtempSync('fs-test-');
|
|
341
|
+
const file = join(dir, 'stream.txt');
|
|
342
|
+
writeFileSync(file, 'stream data');
|
|
343
|
+
|
|
344
|
+
const rs = createReadStream(file);
|
|
345
|
+
const chunks: Buffer[] = [];
|
|
346
|
+
|
|
347
|
+
await new Promise<void>((resolve, reject) => {
|
|
348
|
+
rs.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
349
|
+
rs.on('end', () => resolve());
|
|
350
|
+
rs.on('error', reject);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
const content = Buffer.concat(chunks).toString('utf-8');
|
|
354
|
+
expect(content).toBe('stream data');
|
|
355
|
+
expect(rs.bytesRead).toBe(11);
|
|
356
|
+
|
|
357
|
+
rmSync(file);
|
|
358
|
+
rmdirSync(dir);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
await it('should emit open and ready events', async () => {
|
|
362
|
+
const dir = mkdtempSync('fs-test-');
|
|
363
|
+
const file = join(dir, 'events.txt');
|
|
364
|
+
writeFileSync(file, 'test');
|
|
365
|
+
|
|
366
|
+
const rs = createReadStream(file);
|
|
367
|
+
let openEmitted = false;
|
|
368
|
+
let readyEmitted = false;
|
|
369
|
+
|
|
370
|
+
rs.on('open', () => { openEmitted = true; });
|
|
371
|
+
rs.on('ready', () => { readyEmitted = true; });
|
|
372
|
+
|
|
373
|
+
await new Promise<void>((resolve) => {
|
|
374
|
+
rs.on('end', () => resolve());
|
|
375
|
+
rs.resume();
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
expect(openEmitted).toBeTruthy();
|
|
379
|
+
expect(readyEmitted).toBeTruthy();
|
|
380
|
+
|
|
381
|
+
rmSync(file);
|
|
382
|
+
rmdirSync(dir);
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// ==================== createWriteStream ====================
|
|
387
|
+
|
|
388
|
+
await describe('fs.createWriteStream', async () => {
|
|
389
|
+
await it('should write file contents via stream', async () => {
|
|
390
|
+
const dir = mkdtempSync('fs-test-');
|
|
391
|
+
const file = join(dir, 'ws.txt');
|
|
392
|
+
|
|
393
|
+
const ws = createWriteStream(file, {});
|
|
394
|
+
|
|
395
|
+
await new Promise<void>((resolve, reject) => {
|
|
396
|
+
ws.on('open', () => {
|
|
397
|
+
ws.write('hello ');
|
|
398
|
+
ws.end('world');
|
|
399
|
+
});
|
|
400
|
+
ws.on('finish', () => resolve());
|
|
401
|
+
ws.on('error', reject);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
const content = String(readFileSync(file, 'utf-8'));
|
|
405
|
+
expect(content).toBe('hello world');
|
|
406
|
+
|
|
407
|
+
rmSync(file);
|
|
408
|
+
rmdirSync(dir);
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// ==================== promises.rename ====================
|
|
413
|
+
|
|
414
|
+
await describe('fs.promises.rename', async () => {
|
|
415
|
+
await it('should rename a file', async () => {
|
|
416
|
+
const dir = mkdtempSync('fs-test-');
|
|
417
|
+
const oldPath = join(dir, 'old.txt');
|
|
418
|
+
const newPath = join(dir, 'new.txt');
|
|
419
|
+
writeFileSync(oldPath, 'data');
|
|
420
|
+
|
|
421
|
+
await promises.rename(oldPath, newPath);
|
|
422
|
+
expect(existsSync(newPath)).toBeTruthy();
|
|
423
|
+
expect(existsSync(oldPath)).toBeFalsy();
|
|
424
|
+
|
|
425
|
+
rmSync(newPath);
|
|
426
|
+
rmdirSync(dir);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// ==================== promises.copyFile ====================
|
|
431
|
+
|
|
432
|
+
await describe('fs.promises.copyFile', async () => {
|
|
433
|
+
await it('should copy a file', async () => {
|
|
434
|
+
const dir = mkdtempSync('fs-test-');
|
|
435
|
+
const src = join(dir, 'src.txt');
|
|
436
|
+
const dest = join(dir, 'dest.txt');
|
|
437
|
+
writeFileSync(src, 'copy data');
|
|
438
|
+
|
|
439
|
+
await promises.copyFile(src, dest);
|
|
440
|
+
expect(existsSync(dest)).toBeTruthy();
|
|
441
|
+
expect(String(readFileSync(dest, 'utf-8'))).toBe('copy data');
|
|
442
|
+
|
|
443
|
+
rmSync(src);
|
|
444
|
+
rmSync(dest);
|
|
445
|
+
rmdirSync(dir);
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// ==================== promises.access ====================
|
|
450
|
+
|
|
451
|
+
await describe('fs.promises.access', async () => {
|
|
452
|
+
await it('should resolve for existing file', async () => {
|
|
453
|
+
const dir = mkdtempSync('fs-test-');
|
|
454
|
+
const file = join(dir, 'test.txt');
|
|
455
|
+
writeFileSync(file, '');
|
|
456
|
+
|
|
457
|
+
await promises.access(file);
|
|
458
|
+
|
|
459
|
+
rmSync(file);
|
|
460
|
+
rmdirSync(dir);
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
await it('should reject for non-existing file', async () => {
|
|
464
|
+
let threw = false;
|
|
465
|
+
try {
|
|
466
|
+
await promises.access('/nonexistent/path/file.txt');
|
|
467
|
+
} catch {
|
|
468
|
+
threw = true;
|
|
469
|
+
}
|
|
470
|
+
expect(threw).toBeTruthy();
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
// ==================== promises.appendFile ====================
|
|
475
|
+
|
|
476
|
+
await describe('fs.promises.appendFile', async () => {
|
|
477
|
+
await it('should append data to a file', async () => {
|
|
478
|
+
const dir = mkdtempSync('fs-test-');
|
|
479
|
+
const file = join(dir, 'append.txt');
|
|
480
|
+
writeFileSync(file, 'hello');
|
|
481
|
+
|
|
482
|
+
await promises.appendFile(file, ' world');
|
|
483
|
+
expect(String(readFileSync(file, 'utf-8'))).toBe('hello world');
|
|
484
|
+
|
|
485
|
+
rmSync(file);
|
|
486
|
+
rmdirSync(dir);
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
// ==================== promises.truncate ====================
|
|
491
|
+
|
|
492
|
+
await describe('fs.promises.truncate', async () => {
|
|
493
|
+
await it('should truncate a file', async () => {
|
|
494
|
+
const dir = mkdtempSync('fs-test-');
|
|
495
|
+
const file = join(dir, 'trunc.txt');
|
|
496
|
+
writeFileSync(file, 'hello world');
|
|
497
|
+
|
|
498
|
+
await promises.truncate(file);
|
|
499
|
+
expect(String(readFileSync(file, 'utf-8'))).toBe('');
|
|
500
|
+
|
|
501
|
+
rmSync(file);
|
|
502
|
+
rmdirSync(dir);
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
};
|