memfs 4.1.0 → 4.2.0
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 +10 -7
- package/demo/runkit.js +5 -0
- package/lib/Dirent.js +1 -0
- package/lib/Dirent.js.map +1 -0
- package/lib/Stats.js +2 -2
- package/lib/Stats.js.map +1 -0
- package/lib/__tests__/util.js +1 -0
- package/lib/__tests__/util.js.map +1 -0
- package/lib/cas/types.d.ts +10 -0
- package/lib/{node/types/callback.js → cas/types.js} +1 -0
- package/lib/cas/types.js.map +1 -0
- package/lib/constants.js +1 -0
- package/lib/constants.js.map +1 -0
- package/lib/consts/AMODE.js +1 -0
- package/lib/consts/AMODE.js.map +1 -0
- package/lib/consts/FLAG.d.ts +6 -0
- package/lib/consts/FLAG.js +1 -0
- package/lib/consts/FLAG.js.map +1 -0
- package/lib/crud/__tests__/matryoshka.test.d.ts +1 -0
- package/lib/crud/__tests__/matryoshka.test.js +69 -0
- package/lib/crud/__tests__/matryoshka.test.js.map +1 -0
- package/lib/crud/__tests__/testCrudfs.d.ts +6 -0
- package/lib/crud/__tests__/testCrudfs.js +278 -0
- package/lib/crud/__tests__/testCrudfs.js.map +1 -0
- package/lib/crud/types.d.ts +80 -0
- package/lib/{node/types/promises.js → crud/types.js} +1 -0
- package/lib/crud/types.js.map +1 -0
- package/lib/crud/util.d.ts +2 -0
- package/lib/crud/util.js +11 -0
- package/lib/crud/util.js.map +1 -0
- package/lib/crud-to-cas/CrudCas.d.ts +14 -0
- package/lib/crud-to-cas/CrudCas.js +57 -0
- package/lib/crud-to-cas/CrudCas.js.map +1 -0
- package/lib/crud-to-cas/__tests__/CrudCas.test.d.ts +1 -0
- package/lib/crud-to-cas/__tests__/CrudCas.test.js +38 -0
- package/lib/crud-to-cas/__tests__/CrudCas.test.js.map +1 -0
- package/lib/crud-to-cas/__tests__/testCasfs.d.ts +9 -0
- package/lib/crud-to-cas/__tests__/testCasfs.js +108 -0
- package/lib/crud-to-cas/__tests__/testCasfs.js.map +1 -0
- package/lib/crud-to-cas/index.d.ts +1 -0
- package/lib/crud-to-cas/index.js +6 -0
- package/lib/crud-to-cas/index.js.map +1 -0
- package/lib/crud-to-cas/util.d.ts +2 -0
- package/lib/crud-to-cas/util.js +13 -0
- package/lib/crud-to-cas/util.js.map +1 -0
- package/lib/encoding.js +1 -0
- package/lib/encoding.js.map +1 -0
- package/lib/fsa/types.js +1 -0
- package/lib/fsa/types.js.map +1 -0
- package/lib/fsa-to-crud/FsaCrud.d.ts +15 -0
- package/lib/fsa-to-crud/FsaCrud.js +191 -0
- package/lib/fsa-to-crud/FsaCrud.js.map +1 -0
- package/lib/fsa-to-crud/__tests__/FsaCrud.test.d.ts +1 -0
- package/lib/fsa-to-crud/__tests__/FsaCrud.test.js +17 -0
- package/lib/fsa-to-crud/__tests__/FsaCrud.test.js.map +1 -0
- package/lib/fsa-to-crud/index.d.ts +1 -0
- package/lib/fsa-to-crud/index.js +6 -0
- package/lib/fsa-to-crud/index.js.map +1 -0
- package/lib/fsa-to-crud/util.d.ts +5 -0
- package/lib/fsa-to-crud/util.js +12 -0
- package/lib/fsa-to-crud/util.js.map +1 -0
- package/lib/fsa-to-node/FsaNodeCore.d.ts +3 -2
- package/lib/fsa-to-node/FsaNodeCore.js +109 -87
- package/lib/fsa-to-node/FsaNodeCore.js.map +1 -0
- package/lib/fsa-to-node/FsaNodeDirent.js +1 -0
- package/lib/fsa-to-node/FsaNodeDirent.js.map +1 -0
- package/lib/fsa-to-node/FsaNodeFs.d.ts +14 -2
- package/lib/fsa-to-node/FsaNodeFs.js +156 -143
- package/lib/fsa-to-node/FsaNodeFs.js.map +1 -0
- package/lib/fsa-to-node/FsaNodeFsOpenFile.js +13 -25
- package/lib/fsa-to-node/FsaNodeFsOpenFile.js.map +1 -0
- package/lib/fsa-to-node/FsaNodeReadStream.js +14 -24
- package/lib/fsa-to-node/FsaNodeReadStream.js.map +1 -0
- package/lib/fsa-to-node/FsaNodeStats.js +1 -0
- package/lib/fsa-to-node/FsaNodeStats.js.map +1 -0
- package/lib/fsa-to-node/FsaNodeWriteStream.js +35 -47
- package/lib/fsa-to-node/FsaNodeWriteStream.js.map +1 -0
- package/lib/fsa-to-node/__tests__/FsaNodeFs.test.js +357 -348
- package/lib/fsa-to-node/__tests__/FsaNodeFs.test.js.map +1 -0
- package/lib/fsa-to-node/__tests__/util.test.js +4 -0
- package/lib/fsa-to-node/__tests__/util.test.js.map +1 -0
- package/lib/fsa-to-node/constants.js +1 -0
- package/lib/fsa-to-node/constants.js.map +1 -0
- package/lib/fsa-to-node/index.js +1 -0
- package/lib/fsa-to-node/index.js.map +1 -0
- package/lib/fsa-to-node/json.js +1 -0
- package/lib/fsa-to-node/json.js.map +1 -0
- package/lib/fsa-to-node/types.js +1 -0
- package/lib/fsa-to-node/types.js.map +1 -0
- package/lib/fsa-to-node/util.js +7 -13
- package/lib/fsa-to-node/util.js.map +1 -0
- package/lib/fsa-to-node/worker/FsaNodeSyncAdapterWorker.js +31 -41
- package/lib/fsa-to-node/worker/FsaNodeSyncAdapterWorker.js.map +1 -0
- package/lib/fsa-to-node/worker/FsaNodeSyncWorker.js +91 -105
- package/lib/fsa-to-node/worker/FsaNodeSyncWorker.js.map +1 -0
- package/lib/fsa-to-node/worker/SyncMessenger.js +4 -12
- package/lib/fsa-to-node/worker/SyncMessenger.js.map +1 -0
- package/lib/fsa-to-node/worker/constants.js +1 -0
- package/lib/fsa-to-node/worker/constants.js.map +1 -0
- package/lib/fsa-to-node/worker/types.js +1 -0
- package/lib/fsa-to-node/worker/types.js.map +1 -0
- package/lib/index.d.ts +4 -1
- package/lib/index.js +8 -6
- package/lib/index.js.map +1 -0
- package/lib/internal/buffer.js +1 -0
- package/lib/internal/buffer.js.map +1 -0
- package/lib/internal/errors.js +1 -0
- package/lib/internal/errors.js.map +1 -0
- package/lib/node/FileHandle.js +1 -0
- package/lib/node/FileHandle.js.map +1 -0
- package/lib/node/FsPromises.d.ts +86 -0
- package/lib/node/FsPromises.js +54 -0
- package/lib/node/FsPromises.js.map +1 -0
- package/lib/node/constants.js +2 -1
- package/lib/node/constants.js.map +1 -0
- package/lib/node/lists/fsCallbackApiList.d.ts +2 -0
- package/lib/node/lists/fsCallbackApiList.js +47 -0
- package/lib/node/lists/fsCallbackApiList.js.map +1 -0
- package/lib/node/lists/fsCommonObjectsList.d.ts +2 -0
- package/lib/node/lists/fsCommonObjectsList.js +19 -0
- package/lib/node/lists/fsCommonObjectsList.js.map +1 -0
- package/lib/node/lists/fsSynchronousApiList.d.ts +2 -0
- package/lib/node/lists/fsSynchronousApiList.js +46 -0
- package/lib/node/lists/fsSynchronousApiList.js.map +1 -0
- package/lib/node/options.js +1 -0
- package/lib/node/options.js.map +1 -0
- package/lib/node/types/{callback.d.ts → FsCallbackApi.d.ts} +49 -40
- package/lib/node/types/FsCallbackApi.js +3 -0
- package/lib/node/types/FsCallbackApi.js.map +1 -0
- package/lib/node/types/FsCommonObjects.d.ts +4 -4
- package/lib/node/types/FsCommonObjects.js +1 -0
- package/lib/node/types/FsCommonObjects.js.map +1 -0
- package/lib/node/types/{promises.d.ts → FsPromisesApi.d.ts} +11 -0
- package/lib/node/types/FsPromisesApi.js +3 -0
- package/lib/node/types/FsPromisesApi.js.map +1 -0
- package/lib/node/types/FsSynchronousApi.d.ts +64 -58
- package/lib/node/types/FsSynchronousApi.js +1 -0
- package/lib/node/types/FsSynchronousApi.js.map +1 -0
- package/lib/node/types/index.d.ts +2 -2
- package/lib/node/types/index.js +1 -0
- package/lib/node/types/index.js.map +1 -0
- package/lib/node/types/misc.d.ts +20 -0
- package/lib/node/types/misc.js +1 -0
- package/lib/node/types/misc.js.map +1 -0
- package/lib/node/types/options.d.ts +62 -0
- package/lib/node/types/options.js +1 -0
- package/lib/node/types/options.js.map +1 -0
- package/lib/node/util.d.ts +2 -1
- package/lib/node/util.js +30 -1
- package/lib/node/util.js.map +1 -0
- package/lib/node-to-crud/NodeCrud.d.ts +22 -0
- package/lib/node-to-crud/NodeCrud.js +233 -0
- package/lib/node-to-crud/NodeCrud.js.map +1 -0
- package/lib/node-to-crud/__tests__/FsaCrud.test.d.ts +1 -0
- package/lib/node-to-crud/__tests__/FsaCrud.test.js +18 -0
- package/lib/node-to-crud/__tests__/FsaCrud.test.js.map +1 -0
- package/lib/node-to-crud/index.d.ts +1 -0
- package/lib/node-to-crud/index.js +6 -0
- package/lib/node-to-crud/index.js.map +1 -0
- package/lib/node-to-fsa/NodeFileSystemDirectoryHandle.d.ts +3 -2
- package/lib/node-to-fsa/NodeFileSystemDirectoryHandle.js +112 -151
- package/lib/node-to-fsa/NodeFileSystemDirectoryHandle.js.map +1 -0
- package/lib/node-to-fsa/NodeFileSystemFileHandle.js +25 -36
- package/lib/node-to-fsa/NodeFileSystemFileHandle.js.map +1 -0
- package/lib/node-to-fsa/NodeFileSystemHandle.js +3 -13
- package/lib/node-to-fsa/NodeFileSystemHandle.js.map +1 -0
- package/lib/node-to-fsa/NodeFileSystemSyncAccessHandle.js +42 -62
- package/lib/node-to-fsa/NodeFileSystemSyncAccessHandle.js.map +1 -0
- package/lib/node-to-fsa/NodeFileSystemWritableFileStream.js +92 -116
- package/lib/node-to-fsa/NodeFileSystemWritableFileStream.js.map +1 -0
- package/lib/node-to-fsa/NodePermissionStatus.js +1 -0
- package/lib/node-to-fsa/NodePermissionStatus.js.map +1 -0
- package/lib/node-to-fsa/__tests__/NodeFileSystemDirectoryHandle.test.js +175 -234
- package/lib/node-to-fsa/__tests__/NodeFileSystemDirectoryHandle.test.js.map +1 -0
- package/lib/node-to-fsa/__tests__/NodeFileSystemFileHandle.test.js +91 -99
- package/lib/node-to-fsa/__tests__/NodeFileSystemFileHandle.test.js.map +1 -0
- package/lib/node-to-fsa/__tests__/NodeFileSystemHandle.test.js +10 -18
- package/lib/node-to-fsa/__tests__/NodeFileSystemHandle.test.js.map +1 -0
- package/lib/node-to-fsa/__tests__/NodeFileSystemSyncAccessHandle.test.js +70 -78
- package/lib/node-to-fsa/__tests__/NodeFileSystemSyncAccessHandle.test.js.map +1 -0
- package/lib/node-to-fsa/__tests__/NodeFileSystemWritableFileStream.test.js +31 -39
- package/lib/node-to-fsa/__tests__/NodeFileSystemWritableFileStream.test.js.map +1 -0
- package/lib/node-to-fsa/__tests__/scenarios.test.js +18 -26
- package/lib/node-to-fsa/__tests__/scenarios.test.js.map +1 -0
- package/lib/node-to-fsa/__tests__/util.test.js +5 -0
- package/lib/node-to-fsa/__tests__/util.test.js.map +1 -0
- package/lib/node-to-fsa/index.js +6 -18
- package/lib/node-to-fsa/index.js.map +1 -0
- package/lib/node-to-fsa/types.d.ts +5 -2
- package/lib/node-to-fsa/types.js +1 -0
- package/lib/node-to-fsa/types.js.map +1 -0
- package/lib/node-to-fsa/util.js +3 -0
- package/lib/node-to-fsa/util.js.map +1 -0
- package/lib/node.js +1 -0
- package/lib/node.js.map +1 -0
- package/lib/print/__tests__/index.test.d.ts +1 -0
- package/lib/print/__tests__/index.test.js +77 -0
- package/lib/print/__tests__/index.test.js.map +1 -0
- package/lib/print/index.d.ts +8 -0
- package/lib/print/index.js +33 -0
- package/lib/print/index.js.map +1 -0
- package/lib/process.js +1 -0
- package/lib/process.js.map +1 -0
- package/lib/setImmediate.js +1 -0
- package/lib/setImmediate.js.map +1 -0
- package/lib/setTimeoutUnref.js +1 -0
- package/lib/setTimeoutUnref.js.map +1 -0
- package/lib/snapshot/__tests__/async.test.d.ts +1 -0
- package/lib/snapshot/__tests__/async.test.js +63 -0
- package/lib/snapshot/__tests__/async.test.js.map +1 -0
- package/lib/snapshot/__tests__/binary.test.d.ts +1 -0
- package/lib/snapshot/__tests__/binary.test.js +59 -0
- package/lib/snapshot/__tests__/binary.test.js.map +1 -0
- package/lib/snapshot/__tests__/json.test.d.ts +1 -0
- package/lib/snapshot/__tests__/json.test.js +68 -0
- package/lib/snapshot/__tests__/json.test.js.map +1 -0
- package/lib/snapshot/__tests__/sync.test.d.ts +1 -0
- package/lib/snapshot/__tests__/sync.test.js +63 -0
- package/lib/snapshot/__tests__/sync.test.js.map +1 -0
- package/lib/snapshot/async.d.ts +3 -0
- package/lib/snapshot/async.js +59 -0
- package/lib/snapshot/async.js.map +1 -0
- package/lib/snapshot/binary.d.ts +6 -0
- package/lib/snapshot/binary.js +31 -0
- package/lib/snapshot/binary.js.map +1 -0
- package/lib/snapshot/constants.d.ts +5 -0
- package/lib/snapshot/constants.js +3 -0
- package/lib/snapshot/constants.js.map +1 -0
- package/lib/snapshot/index.d.ts +5 -0
- package/lib/snapshot/index.js +8 -0
- package/lib/snapshot/index.js.map +1 -0
- package/lib/snapshot/json.d.ts +10 -0
- package/lib/snapshot/json.js +31 -0
- package/lib/snapshot/json.js.map +1 -0
- package/lib/snapshot/shared.d.ts +2 -0
- package/lib/snapshot/shared.js +6 -0
- package/lib/snapshot/shared.js.map +1 -0
- package/lib/snapshot/sync.d.ts +3 -0
- package/lib/snapshot/sync.js +59 -0
- package/lib/snapshot/sync.js.map +1 -0
- package/lib/snapshot/types.d.ts +30 -0
- package/lib/snapshot/types.js +3 -0
- package/lib/snapshot/types.js.map +1 -0
- package/lib/volume-localstorage.js +1 -0
- package/lib/volume-localstorage.js.map +1 -0
- package/lib/volume.d.ts +18 -7
- package/lib/volume.js +25 -16
- package/lib/volume.js.map +1 -0
- package/lib/webfs/index.js +1 -0
- package/lib/webfs/index.js.map +1 -0
- package/package.json +67 -26
- package/lib/getBigInt.js +0 -5
- package/lib/node/promises.d.ts +0 -2
- package/lib/node/promises.js +0 -86
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
const __1 = require("../..");
|
|
13
4
|
const node_to_fsa_1 = require("../../node-to-fsa");
|
|
@@ -15,26 +6,35 @@ const FsaNodeFs_1 = require("../FsaNodeFs");
|
|
|
15
6
|
const thingies_1 = require("thingies");
|
|
16
7
|
const util_1 = require("../../__tests__/util");
|
|
17
8
|
const setup = (json = null, mode = 'readwrite') => {
|
|
18
|
-
const mfs = (0, __1.memfs)({ mountpoint: json });
|
|
9
|
+
const { fs: mfs, vol } = (0, __1.memfs)({ mountpoint: json });
|
|
19
10
|
const dir = (0, node_to_fsa_1.nodeToFsa)(mfs, '/mountpoint', { mode, syncHandleAllowed: true });
|
|
20
11
|
const fs = new FsaNodeFs_1.FsaNodeFs(dir);
|
|
21
|
-
return { fs, mfs, dir };
|
|
12
|
+
return { fs, mfs, vol, dir };
|
|
22
13
|
};
|
|
23
14
|
(0, util_1.onlyOnNode20)('FsaNodeFs', () => {
|
|
24
15
|
describe('.mkdir()', () => {
|
|
25
|
-
test('can create a sub-folder', () =>
|
|
16
|
+
test('can create a sub-folder', async () => {
|
|
17
|
+
const { fs, mfs } = setup();
|
|
18
|
+
await new Promise((resolve, reject) => fs.mkdir('/test', err => {
|
|
19
|
+
if (err)
|
|
20
|
+
return reject(err);
|
|
21
|
+
return resolve();
|
|
22
|
+
}));
|
|
23
|
+
expect(mfs.statSync('/mountpoint/test').isDirectory()).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
test('can create a sub-folder with trailing slash', async () => {
|
|
26
26
|
const { fs, mfs } = setup();
|
|
27
|
-
|
|
27
|
+
await new Promise((resolve, reject) => fs.mkdir('/test/', err => {
|
|
28
28
|
if (err)
|
|
29
29
|
return reject(err);
|
|
30
30
|
return resolve();
|
|
31
31
|
}));
|
|
32
32
|
expect(mfs.statSync('/mountpoint/test').isDirectory()).toBe(true);
|
|
33
|
-
})
|
|
34
|
-
test('throws when creating sub-sub-folder', () =>
|
|
33
|
+
});
|
|
34
|
+
test('throws when creating sub-sub-folder', async () => {
|
|
35
35
|
const { fs } = setup();
|
|
36
36
|
try {
|
|
37
|
-
|
|
37
|
+
await new Promise((resolve, reject) => fs.mkdir('/test/subtest', err => {
|
|
38
38
|
if (err)
|
|
39
39
|
return reject(err);
|
|
40
40
|
return resolve();
|
|
@@ -44,210 +44,210 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
44
44
|
catch (error) {
|
|
45
45
|
expect(error.code).toBe('ENOENT');
|
|
46
46
|
}
|
|
47
|
-
})
|
|
48
|
-
test('can create sub-sub-folder with "recursive" flag', () =>
|
|
47
|
+
});
|
|
48
|
+
test('can create sub-sub-folder with "recursive" flag', async () => {
|
|
49
49
|
const { fs, mfs } = setup();
|
|
50
|
-
|
|
50
|
+
await new Promise((resolve, reject) => fs.mkdir('/test/subtest', { recursive: true }, err => {
|
|
51
51
|
if (err)
|
|
52
52
|
return reject(err);
|
|
53
53
|
return resolve();
|
|
54
54
|
}));
|
|
55
55
|
expect(mfs.statSync('/mountpoint/test/subtest').isDirectory()).toBe(true);
|
|
56
|
-
})
|
|
57
|
-
test('can create sub-sub-folder with "recursive" flag with Promises API', () =>
|
|
56
|
+
});
|
|
57
|
+
test('can create sub-sub-folder with "recursive" flag with Promises API', async () => {
|
|
58
58
|
const { fs, mfs } = setup();
|
|
59
|
-
|
|
59
|
+
await fs.promises.mkdir('/test/subtest', { recursive: true });
|
|
60
60
|
expect(mfs.statSync('/mountpoint/test/subtest').isDirectory()).toBe(true);
|
|
61
|
-
})
|
|
62
|
-
test('cannot create a folder over a file', () =>
|
|
61
|
+
});
|
|
62
|
+
test('cannot create a folder over a file', async () => {
|
|
63
63
|
const { fs } = setup({ file: 'test' });
|
|
64
64
|
try {
|
|
65
|
-
|
|
65
|
+
await fs.promises.mkdir('/file/folder', { recursive: true });
|
|
66
66
|
throw new Error('Expected error');
|
|
67
67
|
}
|
|
68
68
|
catch (error) {
|
|
69
69
|
expect(error.code).toBe('ENOTDIR');
|
|
70
70
|
}
|
|
71
|
-
})
|
|
71
|
+
});
|
|
72
72
|
});
|
|
73
73
|
describe('.mkdtemp()', () => {
|
|
74
|
-
test('can create a temporary folder', () =>
|
|
74
|
+
test('can create a temporary folder', async () => {
|
|
75
75
|
const { fs, mfs } = setup();
|
|
76
|
-
const dirname = (
|
|
76
|
+
const dirname = (await fs.promises.mkdtemp('prefix--'));
|
|
77
77
|
expect(dirname.startsWith('prefix--')).toBe(true);
|
|
78
78
|
expect(mfs.statSync('/mountpoint/' + dirname).isDirectory()).toBe(true);
|
|
79
|
-
})
|
|
79
|
+
});
|
|
80
80
|
});
|
|
81
81
|
describe('.rmdir()', () => {
|
|
82
|
-
test('can remove an empty folder', () =>
|
|
83
|
-
const { fs,
|
|
84
|
-
|
|
85
|
-
expect(
|
|
86
|
-
})
|
|
87
|
-
test('throws when attempts to remove non-empty folder', () =>
|
|
88
|
-
const { fs,
|
|
82
|
+
test('can remove an empty folder', async () => {
|
|
83
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
84
|
+
await fs.promises.rmdir('/empty-folder');
|
|
85
|
+
expect(vol.toJSON()).toStrictEqual({ '/mountpoint/folder/file': 'test' });
|
|
86
|
+
});
|
|
87
|
+
test('throws when attempts to remove non-empty folder', async () => {
|
|
88
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
89
89
|
try {
|
|
90
|
-
|
|
90
|
+
await fs.promises.rmdir('/folder');
|
|
91
91
|
throw new Error('Expected error');
|
|
92
92
|
}
|
|
93
93
|
catch (error) {
|
|
94
94
|
expect(error.code).toBe('ENOTEMPTY');
|
|
95
|
-
expect(
|
|
95
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
96
96
|
'/mountpoint/folder/file': 'test',
|
|
97
97
|
'/mountpoint/empty-folder': null,
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
|
-
})
|
|
101
|
-
test('can remove non-empty directory recursively', () =>
|
|
102
|
-
const { fs,
|
|
103
|
-
|
|
104
|
-
expect(
|
|
100
|
+
});
|
|
101
|
+
test('can remove non-empty directory recursively', async () => {
|
|
102
|
+
const { fs, vol } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
103
|
+
await fs.promises.rmdir('/folder', { recursive: true });
|
|
104
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
105
105
|
'/mountpoint/empty-folder': null,
|
|
106
106
|
});
|
|
107
|
-
})
|
|
108
|
-
test('can remove starting from root folder', () =>
|
|
109
|
-
const { fs,
|
|
110
|
-
|
|
111
|
-
expect(
|
|
107
|
+
});
|
|
108
|
+
test('can remove starting from root folder', async () => {
|
|
109
|
+
const { fs, vol } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
110
|
+
await fs.promises.rmdir('/', { recursive: true });
|
|
111
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
112
112
|
'/mountpoint': null,
|
|
113
113
|
});
|
|
114
|
-
})
|
|
114
|
+
});
|
|
115
115
|
});
|
|
116
116
|
describe('.rm()', () => {
|
|
117
|
-
test('can remove an empty folder', () =>
|
|
118
|
-
const { fs,
|
|
119
|
-
|
|
120
|
-
expect(
|
|
121
|
-
})
|
|
122
|
-
test('throws when attempts to remove non-empty folder', () =>
|
|
123
|
-
const { fs,
|
|
117
|
+
test('can remove an empty folder', async () => {
|
|
118
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
119
|
+
await fs.promises.rm('/empty-folder');
|
|
120
|
+
expect(vol.toJSON()).toStrictEqual({ '/mountpoint/folder/file': 'test' });
|
|
121
|
+
});
|
|
122
|
+
test('throws when attempts to remove non-empty folder', async () => {
|
|
123
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
124
124
|
try {
|
|
125
|
-
|
|
125
|
+
await fs.promises.rm('/folder');
|
|
126
126
|
throw new Error('Expected error');
|
|
127
127
|
}
|
|
128
128
|
catch (error) {
|
|
129
129
|
expect(error.code).toBe('ENOTEMPTY');
|
|
130
|
-
expect(
|
|
130
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
131
131
|
'/mountpoint/folder/file': 'test',
|
|
132
132
|
'/mountpoint/empty-folder': null,
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
-
})
|
|
136
|
-
test('can remove non-empty directory recursively', () =>
|
|
137
|
-
const { fs,
|
|
138
|
-
|
|
139
|
-
expect(
|
|
135
|
+
});
|
|
136
|
+
test('can remove non-empty directory recursively', async () => {
|
|
137
|
+
const { fs, vol } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
138
|
+
await fs.promises.rm('/folder', { recursive: true });
|
|
139
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
140
140
|
'/mountpoint/empty-folder': null,
|
|
141
141
|
});
|
|
142
|
-
})
|
|
143
|
-
test('throws if path does not exist', () =>
|
|
144
|
-
const { fs,
|
|
142
|
+
});
|
|
143
|
+
test('throws if path does not exist', async () => {
|
|
144
|
+
const { fs, vol } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
145
145
|
try {
|
|
146
|
-
|
|
146
|
+
await fs.promises.rm('/lala/lulu', { recursive: true });
|
|
147
147
|
throw new Error('Expected error');
|
|
148
148
|
}
|
|
149
149
|
catch (error) {
|
|
150
150
|
expect(error.code).toBe('ENOENT');
|
|
151
|
-
expect(
|
|
151
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
152
152
|
'/mountpoint/folder/subfolder/file': 'test',
|
|
153
153
|
'/mountpoint/empty-folder': null,
|
|
154
154
|
});
|
|
155
155
|
}
|
|
156
|
-
})
|
|
157
|
-
test('does not throw, if path does not exist, but "force" flag set', () =>
|
|
158
|
-
const { fs } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
159
|
-
|
|
160
|
-
})
|
|
161
|
-
test('can remove a file', () =>
|
|
162
|
-
const { fs,
|
|
163
|
-
|
|
164
|
-
expect(
|
|
156
|
+
});
|
|
157
|
+
test('does not throw, if path does not exist, but "force" flag set', async () => {
|
|
158
|
+
const { fs, vol } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
159
|
+
await fs.promises.rm('/lala/lulu', { recursive: true, force: true });
|
|
160
|
+
});
|
|
161
|
+
test('can remove a file', async () => {
|
|
162
|
+
const { fs, vol } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
163
|
+
await fs.promises.rm('/folder/subfolder/file');
|
|
164
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
165
165
|
'/mountpoint/folder/subfolder': null,
|
|
166
166
|
'/mountpoint/empty-folder': null,
|
|
167
167
|
});
|
|
168
|
-
})
|
|
169
|
-
test('can remove starting from root folder', () =>
|
|
170
|
-
const { fs,
|
|
171
|
-
|
|
172
|
-
expect(
|
|
168
|
+
});
|
|
169
|
+
test('can remove starting from root folder', async () => {
|
|
170
|
+
const { fs, vol } = setup({ folder: { subfolder: { file: 'test' } }, 'empty-folder': null });
|
|
171
|
+
await fs.promises.rm('/', { recursive: true });
|
|
172
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
173
173
|
'/mountpoint': null,
|
|
174
174
|
});
|
|
175
|
-
})
|
|
175
|
+
});
|
|
176
176
|
});
|
|
177
177
|
describe('.unlink()', () => {
|
|
178
|
-
test('can remove a file', () =>
|
|
179
|
-
const { fs,
|
|
180
|
-
const res =
|
|
178
|
+
test('can remove a file', async () => {
|
|
179
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
180
|
+
const res = await fs.promises.unlink('/folder/file');
|
|
181
181
|
expect(res).toBe(undefined);
|
|
182
|
-
expect(
|
|
182
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
183
183
|
'/mountpoint/folder': null,
|
|
184
184
|
'/mountpoint/empty-folder': null,
|
|
185
185
|
});
|
|
186
|
-
})
|
|
187
|
-
test('cannot delete a folder', () =>
|
|
188
|
-
const { fs,
|
|
186
|
+
});
|
|
187
|
+
test('cannot delete a folder', async () => {
|
|
188
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
189
189
|
try {
|
|
190
|
-
|
|
190
|
+
await fs.promises.unlink('/folder');
|
|
191
191
|
throw new Error('Expected error');
|
|
192
192
|
}
|
|
193
193
|
catch (error) {
|
|
194
194
|
expect(error.code).toBe('EISDIR');
|
|
195
|
-
expect(
|
|
195
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
196
196
|
'/mountpoint/folder/file': 'test',
|
|
197
197
|
'/mountpoint/empty-folder': null,
|
|
198
198
|
});
|
|
199
199
|
}
|
|
200
|
-
})
|
|
201
|
-
test('throws when deleting non-existing file', () =>
|
|
202
|
-
const { fs,
|
|
200
|
+
});
|
|
201
|
+
test('throws when deleting non-existing file', async () => {
|
|
202
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
203
203
|
try {
|
|
204
|
-
|
|
204
|
+
await fs.promises.unlink('/folder/not-a-file');
|
|
205
205
|
throw new Error('Expected error');
|
|
206
206
|
}
|
|
207
207
|
catch (error) {
|
|
208
208
|
expect(error.code).toBe('ENOENT');
|
|
209
|
-
expect(
|
|
209
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
210
210
|
'/mountpoint/folder/file': 'test',
|
|
211
211
|
'/mountpoint/empty-folder': null,
|
|
212
212
|
});
|
|
213
213
|
}
|
|
214
|
-
})
|
|
214
|
+
});
|
|
215
215
|
});
|
|
216
216
|
describe('.readFile()', () => {
|
|
217
|
-
test('can read file contents', () =>
|
|
217
|
+
test('can read file contents', async () => {
|
|
218
218
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
219
|
-
const data =
|
|
219
|
+
const data = await fs.promises.readFile('/folder/file');
|
|
220
220
|
expect(data.toString()).toBe('test');
|
|
221
|
-
})
|
|
222
|
-
test('can read file by file handle', () =>
|
|
221
|
+
});
|
|
222
|
+
test('can read file by file handle', async () => {
|
|
223
223
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
224
|
-
const handle =
|
|
224
|
+
const handle = await fs.promises.open('/folder/file');
|
|
225
225
|
expect(typeof handle).toBe('object');
|
|
226
|
-
const data =
|
|
226
|
+
const data = await fs.promises.readFile(handle);
|
|
227
227
|
expect(data.toString()).toBe('test');
|
|
228
|
-
})
|
|
229
|
-
test('can read file by file descriptor', () =>
|
|
228
|
+
});
|
|
229
|
+
test('can read file by file descriptor', async () => {
|
|
230
230
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
231
|
-
const fd =
|
|
231
|
+
const fd = await new Promise(resolve => {
|
|
232
232
|
fs.open('/folder/file', 'r', (err, fd) => resolve(fd));
|
|
233
233
|
});
|
|
234
234
|
expect(typeof fd).toBe('number');
|
|
235
|
-
const data =
|
|
235
|
+
const data = await new Promise(resolve => {
|
|
236
236
|
fs.readFile(fd, { encoding: 'utf8' }, (err, data) => resolve(data));
|
|
237
237
|
});
|
|
238
238
|
expect(data).toBe('test');
|
|
239
|
-
})
|
|
240
|
-
test('cannot read from closed file descriptor', () =>
|
|
239
|
+
});
|
|
240
|
+
test('cannot read from closed file descriptor', async () => {
|
|
241
241
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
242
|
-
const fd =
|
|
242
|
+
const fd = await new Promise(resolve => {
|
|
243
243
|
fs.open('/folder/file', 'r', (err, fd) => resolve(fd));
|
|
244
244
|
});
|
|
245
245
|
expect(typeof fd).toBe('number');
|
|
246
|
-
|
|
246
|
+
await new Promise(resolve => {
|
|
247
247
|
fs.close(fd, () => resolve());
|
|
248
248
|
});
|
|
249
249
|
try {
|
|
250
|
-
|
|
250
|
+
await new Promise((resolve, reject) => {
|
|
251
251
|
fs.readFile(fd, { encoding: 'utf8' }, (err, data) => reject(err));
|
|
252
252
|
});
|
|
253
253
|
throw new Error('Expected error');
|
|
@@ -256,42 +256,42 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
256
256
|
expect(error).toBeInstanceOf(Error);
|
|
257
257
|
expect(error.code).toBe('EBADF');
|
|
258
258
|
}
|
|
259
|
-
})
|
|
259
|
+
});
|
|
260
260
|
});
|
|
261
261
|
describe('.truncate()', () => {
|
|
262
|
-
test('can truncate a file', () =>
|
|
262
|
+
test('can truncate a file', async () => {
|
|
263
263
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
264
|
-
const res =
|
|
264
|
+
const res = await new Promise((resolve, reject) => {
|
|
265
265
|
fs.truncate('/folder/file', 2, (err, res) => (err ? reject(err) : resolve(res)));
|
|
266
266
|
});
|
|
267
267
|
expect(res).toBe(undefined);
|
|
268
268
|
expect(mfs.readFileSync('/mountpoint/folder/file', 'utf8')).toBe('te');
|
|
269
|
-
})
|
|
269
|
+
});
|
|
270
270
|
});
|
|
271
271
|
describe('.ftruncate()', () => {
|
|
272
|
-
test('can truncate a file', () =>
|
|
272
|
+
test('can truncate a file', async () => {
|
|
273
273
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null });
|
|
274
|
-
const handle =
|
|
275
|
-
const res =
|
|
274
|
+
const handle = await fs.promises.open('/folder/file');
|
|
275
|
+
const res = await new Promise((resolve, reject) => {
|
|
276
276
|
fs.ftruncate(handle.fd, 3, (err, res) => (err ? reject(err) : resolve(res)));
|
|
277
277
|
});
|
|
278
278
|
expect(res).toBe(undefined);
|
|
279
279
|
expect(mfs.readFileSync('/mountpoint/folder/file', 'utf8')).toBe('tes');
|
|
280
|
-
})
|
|
280
|
+
});
|
|
281
281
|
});
|
|
282
282
|
describe('.readdir()', () => {
|
|
283
|
-
test('can read directory contents as strings', () =>
|
|
283
|
+
test('can read directory contents as strings', async () => {
|
|
284
284
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
285
|
-
const res = (
|
|
285
|
+
const res = (await fs.promises.readdir('/'));
|
|
286
286
|
expect(res.length).toBe(3);
|
|
287
287
|
expect(res.includes('folder')).toBe(true);
|
|
288
288
|
expect(res.includes('empty-folder')).toBe(true);
|
|
289
289
|
expect(res.includes('f.html')).toBe(true);
|
|
290
|
-
})
|
|
291
|
-
test('can read directory contents with "withFileTypes" flag set', () =>
|
|
290
|
+
});
|
|
291
|
+
test('can read directory contents with "withFileTypes" flag set', async () => {
|
|
292
292
|
var _a, _b, _c, _d;
|
|
293
293
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
294
|
-
const list = (
|
|
294
|
+
const list = (await fs.promises.readdir('/', { withFileTypes: true }));
|
|
295
295
|
expect(list.length).toBe(3);
|
|
296
296
|
const names = list.map(item => item.name);
|
|
297
297
|
expect(names).toStrictEqual(['empty-folder', 'f.html', 'folder']);
|
|
@@ -299,42 +299,42 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
299
299
|
expect((_b = list.find(item => item.name === 'empty-folder')) === null || _b === void 0 ? void 0 : _b.isDirectory()).toBe(true);
|
|
300
300
|
expect((_c = list.find(item => item.name === 'f.html')) === null || _c === void 0 ? void 0 : _c.isFile()).toBe(true);
|
|
301
301
|
expect((_d = list.find(item => item.name === 'f.html')) === null || _d === void 0 ? void 0 : _d.isDirectory()).toBe(false);
|
|
302
|
-
})
|
|
302
|
+
});
|
|
303
303
|
});
|
|
304
304
|
describe('.appendFile()', () => {
|
|
305
|
-
test('can create a file', () =>
|
|
305
|
+
test('can create a file', async () => {
|
|
306
306
|
const { fs, mfs } = setup({});
|
|
307
|
-
|
|
307
|
+
await fs.promises.appendFile('/test.txt', 'a');
|
|
308
308
|
expect(mfs.readFileSync('/mountpoint/test.txt', 'utf8')).toBe('a');
|
|
309
|
-
})
|
|
310
|
-
test('can append to a file', () =>
|
|
309
|
+
});
|
|
310
|
+
test('can append to a file', async () => {
|
|
311
311
|
const { fs, mfs } = setup({});
|
|
312
|
-
|
|
313
|
-
|
|
312
|
+
await fs.promises.appendFile('/test.txt', 'a');
|
|
313
|
+
await fs.promises.appendFile('/test.txt', 'b');
|
|
314
314
|
expect(mfs.readFileSync('/mountpoint/test.txt', 'utf8')).toBe('ab');
|
|
315
|
-
})
|
|
316
|
-
test('can append to a file - 2', () =>
|
|
315
|
+
});
|
|
316
|
+
test('can append to a file - 2', async () => {
|
|
317
317
|
const { fs, mfs } = setup({ file: '123' });
|
|
318
|
-
|
|
318
|
+
await fs.promises.appendFile('file', 'x');
|
|
319
319
|
expect(mfs.readFileSync('/mountpoint/file', 'utf8')).toBe('123x');
|
|
320
|
-
})
|
|
321
|
-
test('can append to a file - 2', () =>
|
|
320
|
+
});
|
|
321
|
+
test('can append to a file - 2', async () => {
|
|
322
322
|
const { fs, mfs } = setup({ file: '123' });
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
await fs.promises.writeFile('cool.txt', 'worlds');
|
|
324
|
+
await fs.promises.appendFile('cool.txt', '!');
|
|
325
325
|
expect(mfs.readFileSync('/mountpoint/cool.txt', 'utf8')).toBe('worlds!');
|
|
326
|
-
})
|
|
326
|
+
});
|
|
327
327
|
});
|
|
328
328
|
describe('.write()', () => {
|
|
329
|
-
test('can write to a file', () =>
|
|
329
|
+
test('can write to a file', async () => {
|
|
330
330
|
const { fs, mfs } = setup({});
|
|
331
|
-
const fd =
|
|
331
|
+
const fd = await new Promise((resolve, reject) => fs.open('/test.txt', 'w', (err, fd) => {
|
|
332
332
|
if (err)
|
|
333
333
|
reject(err);
|
|
334
334
|
else
|
|
335
335
|
resolve(fd);
|
|
336
336
|
}));
|
|
337
|
-
const [bytesWritten, data] =
|
|
337
|
+
const [bytesWritten, data] = await new Promise((resolve, reject) => {
|
|
338
338
|
fs.write(fd, 'a', (err, bytesWritten, data) => {
|
|
339
339
|
if (err)
|
|
340
340
|
reject(err);
|
|
@@ -345,16 +345,16 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
345
345
|
expect(bytesWritten).toBe(1);
|
|
346
346
|
expect(data).toBe('a');
|
|
347
347
|
expect(mfs.readFileSync('/mountpoint/test.txt', 'utf8')).toBe('a');
|
|
348
|
-
})
|
|
349
|
-
test('can write to a file twice sequentially', () =>
|
|
348
|
+
});
|
|
349
|
+
test('can write to a file twice sequentially', async () => {
|
|
350
350
|
const { fs, mfs } = setup({});
|
|
351
|
-
const fd =
|
|
351
|
+
const fd = await new Promise((resolve, reject) => fs.open('/test.txt', 'w', (err, fd) => {
|
|
352
352
|
if (err)
|
|
353
353
|
reject(err);
|
|
354
354
|
else
|
|
355
355
|
resolve(fd);
|
|
356
356
|
}));
|
|
357
|
-
const res1 =
|
|
357
|
+
const res1 = await new Promise((resolve, reject) => {
|
|
358
358
|
fs.write(fd, 'a', (err, bytesWritten, data) => {
|
|
359
359
|
if (err)
|
|
360
360
|
reject(err);
|
|
@@ -364,7 +364,7 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
364
364
|
});
|
|
365
365
|
expect(res1[0]).toBe(1);
|
|
366
366
|
expect(res1[1]).toBe('a');
|
|
367
|
-
const res2 =
|
|
367
|
+
const res2 = await new Promise((resolve, reject) => {
|
|
368
368
|
fs.write(fd, 'bc', (err, bytesWritten, data) => {
|
|
369
369
|
if (err)
|
|
370
370
|
reject(err);
|
|
@@ -375,18 +375,18 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
375
375
|
expect(res2[0]).toBe(2);
|
|
376
376
|
expect(res2[1]).toBe('bc');
|
|
377
377
|
expect(mfs.readFileSync('/mountpoint/test.txt', 'utf8')).toBe('abc');
|
|
378
|
-
})
|
|
378
|
+
});
|
|
379
379
|
});
|
|
380
380
|
describe('.writev()', () => {
|
|
381
|
-
test('can write to a file two buffers', () =>
|
|
381
|
+
test('can write to a file two buffers', async () => {
|
|
382
382
|
const { fs, mfs } = setup({});
|
|
383
|
-
const fd =
|
|
383
|
+
const fd = await new Promise((resolve, reject) => fs.open('/test.txt', 'w', (err, fd) => {
|
|
384
384
|
if (err)
|
|
385
385
|
reject(err);
|
|
386
386
|
else
|
|
387
387
|
resolve(fd);
|
|
388
388
|
}));
|
|
389
|
-
const [bytesWritten, data] =
|
|
389
|
+
const [bytesWritten, data] = await new Promise((resolve, reject) => {
|
|
390
390
|
const buffers = [Buffer.from('a'), Buffer.from('b')];
|
|
391
391
|
fs.writev(fd, buffers, (err, bytesWritten, data) => {
|
|
392
392
|
if (err)
|
|
@@ -397,178 +397,178 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
397
397
|
});
|
|
398
398
|
expect(bytesWritten).toBe(2);
|
|
399
399
|
expect(mfs.readFileSync('/mountpoint/test.txt', 'utf8')).toBe('ab');
|
|
400
|
-
})
|
|
400
|
+
});
|
|
401
401
|
});
|
|
402
402
|
describe('.exists()', () => {
|
|
403
|
-
test('can works for folders and files', () =>
|
|
403
|
+
test('can works for folders and files', async () => {
|
|
404
404
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
405
|
-
const exists = (path) =>
|
|
405
|
+
const exists = async (path) => {
|
|
406
406
|
return new Promise(resolve => {
|
|
407
407
|
fs.exists(path, exists => resolve(exists));
|
|
408
408
|
});
|
|
409
|
-
}
|
|
410
|
-
expect(
|
|
411
|
-
expect(
|
|
412
|
-
expect(
|
|
413
|
-
expect(
|
|
414
|
-
expect(
|
|
415
|
-
expect(
|
|
416
|
-
expect(
|
|
417
|
-
expect(
|
|
418
|
-
})
|
|
409
|
+
};
|
|
410
|
+
expect(await exists('/folder')).toBe(true);
|
|
411
|
+
expect(await exists('/folder/file')).toBe(true);
|
|
412
|
+
expect(await exists('/folder/not-a-file')).toBe(false);
|
|
413
|
+
expect(await exists('/f.html')).toBe(true);
|
|
414
|
+
expect(await exists('/empty-folder')).toBe(true);
|
|
415
|
+
expect(await exists('/')).toBe(true);
|
|
416
|
+
expect(await exists('/asdf')).toBe(false);
|
|
417
|
+
expect(await exists('asdf')).toBe(false);
|
|
418
|
+
});
|
|
419
419
|
});
|
|
420
420
|
describe('.access()', () => {
|
|
421
421
|
describe('files', () => {
|
|
422
|
-
test('succeeds on file existence check', () =>
|
|
422
|
+
test('succeeds on file existence check', async () => {
|
|
423
423
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
424
|
-
|
|
425
|
-
})
|
|
426
|
-
test('succeeds on file "read" check', () =>
|
|
424
|
+
await fs.promises.access('/folder/file', 0 /* AMODE.F_OK */);
|
|
425
|
+
});
|
|
426
|
+
test('succeeds on file "read" check', async () => {
|
|
427
427
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
428
|
-
|
|
429
|
-
})
|
|
430
|
-
test('succeeds on file "write" check, on writable file system', () =>
|
|
428
|
+
await fs.promises.access('/folder/file', 4 /* AMODE.R_OK */);
|
|
429
|
+
});
|
|
430
|
+
test('succeeds on file "write" check, on writable file system', async () => {
|
|
431
431
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
432
|
-
|
|
433
|
-
})
|
|
434
|
-
test('fails on file "write" check, on read-only file system', () =>
|
|
432
|
+
await fs.promises.access('/folder/file', 2 /* AMODE.W_OK */);
|
|
433
|
+
});
|
|
434
|
+
test('fails on file "write" check, on read-only file system', async () => {
|
|
435
435
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' }, 'read');
|
|
436
436
|
try {
|
|
437
|
-
|
|
437
|
+
await fs.promises.access('/folder/file', 2 /* AMODE.W_OK */);
|
|
438
438
|
throw new Error('should not be here');
|
|
439
439
|
}
|
|
440
440
|
catch (error) {
|
|
441
441
|
expect(error.code).toBe('EACCESS');
|
|
442
442
|
}
|
|
443
|
-
})
|
|
444
|
-
test('fails on file "execute" check', () =>
|
|
443
|
+
});
|
|
444
|
+
test('fails on file "execute" check', async () => {
|
|
445
445
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
446
446
|
try {
|
|
447
|
-
|
|
447
|
+
await fs.promises.access('/folder/file', 1 /* AMODE.X_OK */);
|
|
448
448
|
throw new Error('should not be here');
|
|
449
449
|
}
|
|
450
450
|
catch (error) {
|
|
451
451
|
expect(error.code).toBe('EACCESS');
|
|
452
452
|
}
|
|
453
|
-
})
|
|
453
|
+
});
|
|
454
454
|
});
|
|
455
455
|
describe('directories', () => {
|
|
456
|
-
test('succeeds on folder existence check', () =>
|
|
456
|
+
test('succeeds on folder existence check', async () => {
|
|
457
457
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
458
|
-
|
|
459
|
-
})
|
|
460
|
-
test('succeeds on folder "read" check', () =>
|
|
458
|
+
await fs.promises.access('/folder', 0 /* AMODE.F_OK */);
|
|
459
|
+
});
|
|
460
|
+
test('succeeds on folder "read" check', async () => {
|
|
461
461
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
462
|
-
|
|
463
|
-
})
|
|
464
|
-
test('succeeds on folder "write" check, on writable file system', () =>
|
|
462
|
+
await fs.promises.access('/folder', 4 /* AMODE.R_OK */);
|
|
463
|
+
});
|
|
464
|
+
test('succeeds on folder "write" check, on writable file system', async () => {
|
|
465
465
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
466
|
-
|
|
467
|
-
})
|
|
468
|
-
test('fails on folder "write" check, on read-only file system', () =>
|
|
466
|
+
await fs.promises.access('/folder', 2 /* AMODE.W_OK */);
|
|
467
|
+
});
|
|
468
|
+
test('fails on folder "write" check, on read-only file system', async () => {
|
|
469
469
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' }, 'read');
|
|
470
470
|
try {
|
|
471
|
-
|
|
471
|
+
await fs.promises.access('/folder', 2 /* AMODE.W_OK */);
|
|
472
472
|
throw new Error('should not be here');
|
|
473
473
|
}
|
|
474
474
|
catch (error) {
|
|
475
475
|
expect(error.code).toBe('EACCESS');
|
|
476
476
|
}
|
|
477
|
-
})
|
|
478
|
-
test('fails on folder "execute" check', () =>
|
|
477
|
+
});
|
|
478
|
+
test('fails on folder "execute" check', async () => {
|
|
479
479
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
480
480
|
try {
|
|
481
|
-
|
|
481
|
+
await fs.promises.access('/folder', 1 /* AMODE.X_OK */);
|
|
482
482
|
throw new Error('should not be here');
|
|
483
483
|
}
|
|
484
484
|
catch (error) {
|
|
485
485
|
expect(error.code).toBe('EACCESS');
|
|
486
486
|
}
|
|
487
|
-
})
|
|
487
|
+
});
|
|
488
488
|
});
|
|
489
489
|
});
|
|
490
490
|
describe('.rename()', () => {
|
|
491
|
-
test('can rename a file', () =>
|
|
492
|
-
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
493
|
-
|
|
494
|
-
expect(
|
|
491
|
+
test('can rename a file', async () => {
|
|
492
|
+
const { fs, mfs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
493
|
+
await fs.promises.rename('/folder/file', '/folder/file2');
|
|
494
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
495
495
|
'/mountpoint/folder/file2': 'test',
|
|
496
496
|
'/mountpoint/empty-folder': null,
|
|
497
497
|
'/mountpoint/f.html': 'test',
|
|
498
498
|
});
|
|
499
|
-
})
|
|
499
|
+
});
|
|
500
500
|
});
|
|
501
501
|
describe('.stat()', () => {
|
|
502
|
-
test('can stat a file', () =>
|
|
502
|
+
test('can stat a file', async () => {
|
|
503
503
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
504
|
-
const stats =
|
|
504
|
+
const stats = await fs.promises.stat('/folder/file');
|
|
505
505
|
expect(stats.isFile()).toBe(true);
|
|
506
|
-
})
|
|
507
|
-
test('throws "ENOENT" when path is not found', () =>
|
|
506
|
+
});
|
|
507
|
+
test('throws "ENOENT" when path is not found', async () => {
|
|
508
508
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
509
|
-
const [, error] =
|
|
509
|
+
const [, error] = await (0, thingies_1.of)(fs.promises.stat('/folder/repo/.git'));
|
|
510
510
|
expect(error.code).toBe('ENOENT');
|
|
511
|
-
})
|
|
512
|
-
test('throws "ENOTDIR" when sub-folder is a file', () =>
|
|
511
|
+
});
|
|
512
|
+
test('throws "ENOTDIR" when sub-folder is a file', async () => {
|
|
513
513
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
514
|
-
const [, error] =
|
|
514
|
+
const [, error] = await (0, thingies_1.of)(fs.promises.stat('/folder/file/repo/.git'));
|
|
515
515
|
expect(error.code).toBe('ENOTDIR');
|
|
516
|
-
})
|
|
517
|
-
test('can retrieve file size', () =>
|
|
516
|
+
});
|
|
517
|
+
test('can retrieve file size', async () => {
|
|
518
518
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
519
|
-
const stats =
|
|
519
|
+
const stats = await fs.promises.stat('/folder/file');
|
|
520
520
|
expect(stats.size).toBe(4);
|
|
521
|
-
})
|
|
522
|
-
test('can stat a folder', () =>
|
|
521
|
+
});
|
|
522
|
+
test('can stat a folder', async () => {
|
|
523
523
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
524
|
-
const stats =
|
|
524
|
+
const stats = await fs.promises.stat('/folder');
|
|
525
525
|
expect(stats.isFile()).toBe(false);
|
|
526
526
|
expect(stats.isDirectory()).toBe(true);
|
|
527
|
-
})
|
|
528
|
-
test('throws on non-existing path', () =>
|
|
527
|
+
});
|
|
528
|
+
test('throws on non-existing path', async () => {
|
|
529
529
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
530
530
|
try {
|
|
531
|
-
const stats =
|
|
531
|
+
const stats = await fs.promises.stat('/folder/abc');
|
|
532
532
|
throw new Error('should not be here');
|
|
533
533
|
}
|
|
534
534
|
catch (error) {
|
|
535
535
|
expect(error.code).toBe('ENOENT');
|
|
536
536
|
}
|
|
537
|
-
})
|
|
537
|
+
});
|
|
538
538
|
});
|
|
539
539
|
describe('.lstat()', () => {
|
|
540
|
-
test('can stat a file', () =>
|
|
540
|
+
test('can stat a file', async () => {
|
|
541
541
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
542
|
-
const stats =
|
|
542
|
+
const stats = await fs.promises.lstat('/folder/file');
|
|
543
543
|
expect(stats.isFile()).toBe(true);
|
|
544
|
-
})
|
|
545
|
-
test('can retrieve file size', () =>
|
|
544
|
+
});
|
|
545
|
+
test('can retrieve file size', async () => {
|
|
546
546
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
547
|
-
const stats =
|
|
547
|
+
const stats = await fs.promises.lstat('/folder/file');
|
|
548
548
|
expect(stats.size).toBe(4);
|
|
549
|
-
})
|
|
550
|
-
test('can stat a folder', () =>
|
|
549
|
+
});
|
|
550
|
+
test('can stat a folder', async () => {
|
|
551
551
|
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
552
|
-
const stats =
|
|
552
|
+
const stats = await fs.promises.lstat('/folder');
|
|
553
553
|
expect(stats.isFile()).toBe(false);
|
|
554
554
|
expect(stats.isDirectory()).toBe(true);
|
|
555
|
-
})
|
|
556
|
-
test('throws on non-existing path', () =>
|
|
555
|
+
});
|
|
556
|
+
test('throws on non-existing path', async () => {
|
|
557
557
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
558
558
|
try {
|
|
559
|
-
|
|
559
|
+
await fs.promises.lstat('/folder/abc');
|
|
560
560
|
throw new Error('should not be here');
|
|
561
561
|
}
|
|
562
562
|
catch (error) {
|
|
563
563
|
expect(error.code).toBe('ENOENT');
|
|
564
564
|
}
|
|
565
|
-
})
|
|
565
|
+
});
|
|
566
566
|
});
|
|
567
567
|
describe('.fstat()', () => {
|
|
568
|
-
test('can stat a file', () =>
|
|
568
|
+
test('can stat a file', async () => {
|
|
569
569
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
570
|
-
const handle =
|
|
571
|
-
const stats =
|
|
570
|
+
const handle = await fs.promises.open('/folder/file', 'r');
|
|
571
|
+
const stats = await new Promise((resolve, reject) => {
|
|
572
572
|
fs.fstat(handle.fd, (error, stats) => {
|
|
573
573
|
if (error)
|
|
574
574
|
reject(error);
|
|
@@ -577,38 +577,38 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
577
577
|
});
|
|
578
578
|
});
|
|
579
579
|
expect(stats.isFile()).toBe(true);
|
|
580
|
-
})
|
|
580
|
+
});
|
|
581
581
|
});
|
|
582
582
|
describe('.realpath()', () => {
|
|
583
|
-
test('returns file path', () =>
|
|
583
|
+
test('returns file path', async () => {
|
|
584
584
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
585
|
-
const path =
|
|
585
|
+
const path = await fs.promises.realpath('folder/file');
|
|
586
586
|
expect(path).toBe('/folder/file');
|
|
587
|
-
})
|
|
587
|
+
});
|
|
588
588
|
});
|
|
589
589
|
describe('.realpathSync()', () => {
|
|
590
|
-
test('returns file path', () =>
|
|
590
|
+
test('returns file path', async () => {
|
|
591
591
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
592
592
|
const path = fs.realpathSync('folder/file');
|
|
593
593
|
expect(path).toBe('/folder/file');
|
|
594
|
-
})
|
|
594
|
+
});
|
|
595
595
|
});
|
|
596
596
|
describe('.copyFile()', () => {
|
|
597
|
-
test('can copy a file', () =>
|
|
598
|
-
const { fs,
|
|
599
|
-
|
|
600
|
-
expect(
|
|
597
|
+
test('can copy a file', async () => {
|
|
598
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
599
|
+
await fs.promises.copyFile('/folder/file', '/folder/file2');
|
|
600
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
601
601
|
'/mountpoint/folder/file': 'test',
|
|
602
602
|
'/mountpoint/folder/file2': 'test',
|
|
603
603
|
'/mountpoint/empty-folder': null,
|
|
604
604
|
'/mountpoint/f.html': 'test',
|
|
605
605
|
});
|
|
606
|
-
})
|
|
606
|
+
});
|
|
607
607
|
});
|
|
608
608
|
describe('.writeFile()', () => {
|
|
609
|
-
test('can create a new file', () =>
|
|
610
|
-
const { fs,
|
|
611
|
-
const res =
|
|
609
|
+
test('can create a new file', async () => {
|
|
610
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
611
|
+
const res = await new Promise((resolve, reject) => {
|
|
612
612
|
fs.writeFile('/folder/foo', 'bar', error => {
|
|
613
613
|
if (error)
|
|
614
614
|
reject(error);
|
|
@@ -617,19 +617,31 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
617
617
|
});
|
|
618
618
|
});
|
|
619
619
|
expect(res).toBe(undefined);
|
|
620
|
-
expect(
|
|
620
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
621
621
|
'/mountpoint/folder/file': 'test',
|
|
622
622
|
'/mountpoint/folder/foo': 'bar',
|
|
623
623
|
'/mountpoint/empty-folder': null,
|
|
624
624
|
'/mountpoint/f.html': 'test',
|
|
625
625
|
});
|
|
626
|
-
})
|
|
626
|
+
});
|
|
627
|
+
test('throws "EEXIST", if file already exists and O_EXCL flag set', async () => {
|
|
628
|
+
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
629
|
+
const [, err] = await (0, thingies_1.of)(fs.promises.writeFile('/folder/file', 'bar', { flag: 'wx' }));
|
|
630
|
+
expect(err).toBeInstanceOf(Error);
|
|
631
|
+
expect(err.code).toBe('EEXIST');
|
|
632
|
+
});
|
|
633
|
+
test('throws "ENOENT", if file does not exist and O_CREAT flag not set', async () => {
|
|
634
|
+
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
635
|
+
const [, err] = await (0, thingies_1.of)(fs.promises.writeFile('/folder/file2', 'bar', { flag: 2 /* FLAG.O_RDWR */ }));
|
|
636
|
+
expect(err).toBeInstanceOf(Error);
|
|
637
|
+
expect(err.code).toBe('ENOENT');
|
|
638
|
+
});
|
|
627
639
|
});
|
|
628
640
|
describe('.read()', () => {
|
|
629
|
-
test('can read from a file at offset into Buffer', () =>
|
|
641
|
+
test('can read from a file at offset into Buffer', async () => {
|
|
630
642
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
631
|
-
const handle =
|
|
632
|
-
const [buffer, length] =
|
|
643
|
+
const handle = await fs.promises.open('/folder/file', 'r');
|
|
644
|
+
const [buffer, length] = await new Promise((resolve, reject) => {
|
|
633
645
|
const buffer = Buffer.alloc(4);
|
|
634
646
|
fs.read(handle.fd, buffer, 0, 2, 1, (error, bytesRead, buffer) => {
|
|
635
647
|
if (error)
|
|
@@ -640,11 +652,11 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
640
652
|
});
|
|
641
653
|
expect(length).toBe(2);
|
|
642
654
|
expect(buffer.slice(0, 2).toString()).toBe('es');
|
|
643
|
-
})
|
|
644
|
-
test('can read from a file at offset into Uint8Array', () =>
|
|
655
|
+
});
|
|
656
|
+
test('can read from a file at offset into Uint8Array', async () => {
|
|
645
657
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
646
|
-
const handle =
|
|
647
|
-
const [buffer, length] =
|
|
658
|
+
const handle = await fs.promises.open('/folder/file', 'r');
|
|
659
|
+
const [buffer, length] = await new Promise((resolve, reject) => {
|
|
648
660
|
const buffer = new Uint8Array(4);
|
|
649
661
|
fs.read(handle.fd, buffer, 0, 2, 1, (error, bytesRead, buffer) => {
|
|
650
662
|
if (error)
|
|
@@ -656,138 +668,134 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
656
668
|
expect(length).toBe(2);
|
|
657
669
|
expect(buffer[0]).toBe(101);
|
|
658
670
|
expect(buffer[1]).toBe(115);
|
|
659
|
-
})
|
|
671
|
+
});
|
|
660
672
|
});
|
|
661
673
|
describe('.createWriteStream()', () => {
|
|
662
|
-
test('can use stream to write to a new file', () =>
|
|
663
|
-
const { fs,
|
|
674
|
+
test('can use stream to write to a new file', async () => {
|
|
675
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
664
676
|
const stream = fs.createWriteStream('/folder/file2');
|
|
665
677
|
stream.write(Buffer.from('A'));
|
|
666
678
|
stream.write(Buffer.from('BC'));
|
|
667
679
|
stream.write(Buffer.from('DEF'));
|
|
668
680
|
stream.end();
|
|
669
|
-
|
|
681
|
+
await new Promise(resolve => stream.once('close', resolve));
|
|
670
682
|
expect(stream.bytesWritten).toBe(6);
|
|
671
|
-
expect(
|
|
683
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
672
684
|
'/mountpoint/folder/file': 'test',
|
|
673
685
|
'/mountpoint/folder/file2': 'ABCDEF',
|
|
674
686
|
'/mountpoint/empty-folder': null,
|
|
675
687
|
'/mountpoint/f.html': 'test',
|
|
676
688
|
});
|
|
677
|
-
})
|
|
678
|
-
test('can use stream to write to a new file using strings', () =>
|
|
679
|
-
const { fs,
|
|
689
|
+
});
|
|
690
|
+
test('can use stream to write to a new file using strings', async () => {
|
|
691
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
680
692
|
const stream = fs.createWriteStream('/folder/file2');
|
|
681
693
|
stream.write('A');
|
|
682
694
|
stream.write('BC');
|
|
683
695
|
stream.write('DEF');
|
|
684
696
|
stream.end();
|
|
685
|
-
|
|
697
|
+
await new Promise(resolve => stream.once('close', resolve));
|
|
686
698
|
expect(stream.bytesWritten).toBe(6);
|
|
687
|
-
expect(
|
|
699
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
688
700
|
'/mountpoint/folder/file': 'test',
|
|
689
701
|
'/mountpoint/folder/file2': 'ABCDEF',
|
|
690
702
|
'/mountpoint/empty-folder': null,
|
|
691
703
|
'/mountpoint/f.html': 'test',
|
|
692
704
|
});
|
|
693
|
-
})
|
|
694
|
-
test('can use stream to overwrite existing file', () =>
|
|
695
|
-
const { fs,
|
|
705
|
+
});
|
|
706
|
+
test('can use stream to overwrite existing file', async () => {
|
|
707
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
696
708
|
const stream = fs.createWriteStream('/folder/file');
|
|
697
709
|
stream.write(Buffer.from('A'));
|
|
698
710
|
stream.write(Buffer.from('BC'));
|
|
699
711
|
stream.end();
|
|
700
|
-
|
|
712
|
+
await new Promise(resolve => stream.once('close', resolve));
|
|
701
713
|
expect(stream.bytesWritten).toBe(3);
|
|
702
|
-
expect(
|
|
714
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
703
715
|
'/mountpoint/folder/file': 'ABC',
|
|
704
716
|
'/mountpoint/empty-folder': null,
|
|
705
717
|
'/mountpoint/f.html': 'test',
|
|
706
718
|
});
|
|
707
|
-
})
|
|
708
|
-
test('can write by file descriptor', () =>
|
|
709
|
-
const { fs, mfs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
710
|
-
const handle =
|
|
719
|
+
});
|
|
720
|
+
test('can write by file descriptor', async () => {
|
|
721
|
+
const { fs, mfs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
722
|
+
const handle = await fs.promises.open('/folder/file', 'a');
|
|
711
723
|
const stream = fs.createWriteStream('', { fd: handle.fd, start: 1, flags: 'a' });
|
|
712
724
|
stream.write(Buffer.from('BC'));
|
|
713
725
|
stream.end();
|
|
714
|
-
|
|
726
|
+
await new Promise(resolve => stream.once('close', resolve));
|
|
715
727
|
expect(stream.bytesWritten).toBe(2);
|
|
716
|
-
expect(
|
|
728
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
717
729
|
'/mountpoint/folder/file': 'tBCt',
|
|
718
730
|
'/mountpoint/empty-folder': null,
|
|
719
731
|
'/mountpoint/f.html': 'test',
|
|
720
732
|
});
|
|
721
|
-
})
|
|
722
|
-
test('closes file once stream ends', () =>
|
|
733
|
+
});
|
|
734
|
+
test('closes file once stream ends', async () => {
|
|
723
735
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
724
|
-
const handle =
|
|
736
|
+
const handle = await fs.promises.open('/folder/file', 'a');
|
|
725
737
|
const stream = fs.createWriteStream('', { fd: handle.fd, start: 1, flags: 'a' });
|
|
726
738
|
stream.write(Buffer.from('BC'));
|
|
727
|
-
const stat = () =>
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
});
|
|
735
|
-
yield stat();
|
|
739
|
+
const stat = async () => await new Promise((resolve, reject) => fs.fstat(handle.fd, (err, stats) => {
|
|
740
|
+
if (err)
|
|
741
|
+
reject(err);
|
|
742
|
+
else
|
|
743
|
+
resolve(stats);
|
|
744
|
+
}));
|
|
745
|
+
await stat();
|
|
736
746
|
stream.end();
|
|
737
|
-
|
|
738
|
-
const [, error] =
|
|
747
|
+
await (0, thingies_1.until)(async () => {
|
|
748
|
+
const [, error] = await (0, thingies_1.of)(stat());
|
|
739
749
|
return !!error;
|
|
740
|
-
})
|
|
741
|
-
const [, error] =
|
|
750
|
+
});
|
|
751
|
+
const [, error] = await (0, thingies_1.of)(stat());
|
|
742
752
|
expect(error.code).toBe('EBADF');
|
|
743
|
-
})
|
|
744
|
-
test('does not close file if "autoClose" is false', () =>
|
|
753
|
+
});
|
|
754
|
+
test('does not close file if "autoClose" is false', async () => {
|
|
745
755
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
746
|
-
const handle =
|
|
756
|
+
const handle = await fs.promises.open('/folder/file', 'a');
|
|
747
757
|
const stream = fs.createWriteStream('', { fd: handle.fd, start: 1, flags: 'a', autoClose: false });
|
|
748
758
|
stream.write(Buffer.from('BC'));
|
|
749
|
-
const stat = () =>
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
});
|
|
757
|
-
yield stat();
|
|
759
|
+
const stat = async () => await new Promise((resolve, reject) => fs.fstat(handle.fd, (err, stats) => {
|
|
760
|
+
if (err)
|
|
761
|
+
reject(err);
|
|
762
|
+
else
|
|
763
|
+
resolve(stats);
|
|
764
|
+
}));
|
|
765
|
+
await stat();
|
|
758
766
|
stream.end();
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
})
|
|
762
|
-
test('can use stream to add to existing file', () =>
|
|
763
|
-
const { fs,
|
|
767
|
+
await (0, thingies_1.tick)(200);
|
|
768
|
+
await stat();
|
|
769
|
+
});
|
|
770
|
+
test('can use stream to add to existing file', async () => {
|
|
771
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
764
772
|
const stream = fs.createWriteStream('/folder/file', { flags: 'a' });
|
|
765
773
|
stream.write(Buffer.from('A'));
|
|
766
774
|
stream.write(Buffer.from('BC'));
|
|
767
775
|
stream.end();
|
|
768
|
-
|
|
776
|
+
await new Promise(resolve => stream.once('close', resolve));
|
|
769
777
|
expect(stream.bytesWritten).toBe(3);
|
|
770
|
-
expect(
|
|
778
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
771
779
|
'/mountpoint/folder/file': 'ABCt',
|
|
772
780
|
'/mountpoint/empty-folder': null,
|
|
773
781
|
'/mountpoint/f.html': 'test',
|
|
774
782
|
});
|
|
775
|
-
})
|
|
776
|
-
test('can use stream to add to existing file at specified offset', () =>
|
|
777
|
-
const { fs,
|
|
783
|
+
});
|
|
784
|
+
test('can use stream to add to existing file at specified offset', async () => {
|
|
785
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
778
786
|
const stream = fs.createWriteStream('/folder/file', { flags: 'a', start: 1 });
|
|
779
787
|
stream.write(Buffer.from('A'));
|
|
780
788
|
stream.write(Buffer.from('B'));
|
|
781
789
|
stream.end();
|
|
782
|
-
|
|
790
|
+
await new Promise(resolve => stream.once('close', resolve));
|
|
783
791
|
expect(stream.bytesWritten).toBe(2);
|
|
784
|
-
expect(
|
|
792
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
785
793
|
'/mountpoint/folder/file': 'tABt',
|
|
786
794
|
'/mountpoint/empty-folder': null,
|
|
787
795
|
'/mountpoint/f.html': 'test',
|
|
788
796
|
});
|
|
789
|
-
})
|
|
790
|
-
test('throws if "start" option is not a number', () =>
|
|
797
|
+
});
|
|
798
|
+
test('throws if "start" option is not a number', async () => {
|
|
791
799
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
792
800
|
try {
|
|
793
801
|
fs.createWriteStream('/folder/file', { flags: 'a', start: '1' });
|
|
@@ -797,8 +805,8 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
797
805
|
expect(error).toBeInstanceOf(TypeError);
|
|
798
806
|
expect(error.message).toBe('"start" option must be a Number');
|
|
799
807
|
}
|
|
800
|
-
})
|
|
801
|
-
test('throws if "start" option is negative', () =>
|
|
808
|
+
});
|
|
809
|
+
test('throws if "start" option is negative', async () => {
|
|
802
810
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
803
811
|
try {
|
|
804
812
|
fs.createWriteStream('/folder/file', { flags: 'a', start: -1 });
|
|
@@ -808,66 +816,67 @@ const setup = (json = null, mode = 'readwrite') => {
|
|
|
808
816
|
expect(error).toBeInstanceOf(TypeError);
|
|
809
817
|
expect(error.message).toBe('"start" must be >= zero');
|
|
810
818
|
}
|
|
811
|
-
})
|
|
819
|
+
});
|
|
812
820
|
});
|
|
813
821
|
describe('.createReadStream()', () => {
|
|
814
|
-
test('can pipe fs.ReadStream to fs.WriteStream', () =>
|
|
815
|
-
const { fs,
|
|
822
|
+
test('can pipe fs.ReadStream to fs.WriteStream', async () => {
|
|
823
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
816
824
|
const readStream = fs.createReadStream('/folder/file');
|
|
817
825
|
const writeStream = fs.createWriteStream('/folder/file2');
|
|
818
826
|
readStream.pipe(writeStream);
|
|
819
|
-
|
|
820
|
-
expect(
|
|
827
|
+
await new Promise(resolve => writeStream.once('close', resolve));
|
|
828
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
821
829
|
'/mountpoint/folder/file': 'test',
|
|
822
830
|
'/mountpoint/folder/file2': 'test',
|
|
823
831
|
'/mountpoint/empty-folder': null,
|
|
824
832
|
'/mountpoint/f.html': 'test',
|
|
825
833
|
});
|
|
826
|
-
})
|
|
827
|
-
test('emits "open" event', () =>
|
|
834
|
+
});
|
|
835
|
+
test('emits "open" event', async () => {
|
|
828
836
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
829
837
|
const readStream = fs.createReadStream('/folder/file');
|
|
830
|
-
const fd =
|
|
838
|
+
const fd = await new Promise(resolve => readStream.once('open', resolve));
|
|
831
839
|
expect(typeof fd).toBe('number');
|
|
832
|
-
})
|
|
833
|
-
test('emits "ready" event', () =>
|
|
840
|
+
});
|
|
841
|
+
test('emits "ready" event', async () => {
|
|
834
842
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
835
843
|
const readStream = fs.createReadStream('/folder/file');
|
|
836
|
-
|
|
837
|
-
})
|
|
838
|
-
test('emits "close" event', () =>
|
|
844
|
+
await new Promise(resolve => readStream.once('ready', resolve));
|
|
845
|
+
});
|
|
846
|
+
test('emits "close" event', async () => {
|
|
839
847
|
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
840
848
|
const readStream = fs.createReadStream('/folder/file', { emitClose: true });
|
|
841
849
|
const writeStream = fs.createWriteStream('/folder/file2');
|
|
842
850
|
readStream.pipe(writeStream);
|
|
843
|
-
|
|
844
|
-
})
|
|
845
|
-
test('can write to already open file', () =>
|
|
846
|
-
const { fs,
|
|
847
|
-
const handle =
|
|
851
|
+
await new Promise(resolve => readStream.once('close', resolve));
|
|
852
|
+
});
|
|
853
|
+
test('can write to already open file', async () => {
|
|
854
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
855
|
+
const handle = await fs.promises.open('/folder/file');
|
|
848
856
|
const readStream = fs.createReadStream('xyz', { fd: handle.fd });
|
|
849
857
|
const writeStream = fs.createWriteStream('/folder/file2');
|
|
850
858
|
readStream.pipe(writeStream);
|
|
851
|
-
|
|
852
|
-
expect(
|
|
859
|
+
await new Promise(resolve => writeStream.once('close', resolve));
|
|
860
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
853
861
|
'/mountpoint/folder/file': 'test',
|
|
854
862
|
'/mountpoint/folder/file2': 'test',
|
|
855
863
|
'/mountpoint/empty-folder': null,
|
|
856
864
|
'/mountpoint/f.html': 'test',
|
|
857
865
|
});
|
|
858
|
-
})
|
|
859
|
-
test('can read a specified slice of a file', () =>
|
|
860
|
-
const { fs,
|
|
866
|
+
});
|
|
867
|
+
test('can read a specified slice of a file', async () => {
|
|
868
|
+
const { fs, vol } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
|
|
861
869
|
const readStream = fs.createReadStream('/folder/file', { start: 1, end: 2 });
|
|
862
870
|
const writeStream = fs.createWriteStream('/folder/file2');
|
|
863
871
|
readStream.pipe(writeStream);
|
|
864
|
-
|
|
865
|
-
expect(
|
|
872
|
+
await new Promise(resolve => writeStream.once('close', resolve));
|
|
873
|
+
expect(vol.toJSON()).toStrictEqual({
|
|
866
874
|
'/mountpoint/folder/file': 'test',
|
|
867
875
|
'/mountpoint/folder/file2': 'es',
|
|
868
876
|
'/mountpoint/empty-folder': null,
|
|
869
877
|
'/mountpoint/f.html': 'test',
|
|
870
878
|
});
|
|
871
|
-
})
|
|
879
|
+
});
|
|
872
880
|
});
|
|
873
881
|
});
|
|
882
|
+
//# sourceMappingURL=FsaNodeFs.test.js.map
|