@zenfs/core 2.0.0 → 2.1.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.
Files changed (87) hide show
  1. package/dist/backends/backend.js +6 -5
  2. package/dist/backends/cow.d.ts +2 -2
  3. package/dist/backends/cow.js +39 -58
  4. package/dist/backends/fetch.js +27 -29
  5. package/dist/backends/passthrough.d.ts +2 -3
  6. package/dist/backends/passthrough.js +84 -199
  7. package/dist/backends/port.d.ts +16 -3
  8. package/dist/backends/port.js +61 -30
  9. package/dist/backends/single_buffer.d.ts +52 -46
  10. package/dist/backends/single_buffer.js +462 -219
  11. package/dist/backends/store/fs.d.ts +16 -10
  12. package/dist/backends/store/fs.js +227 -242
  13. package/dist/backends/store/store.d.ts +3 -3
  14. package/dist/backends/store/store.js +11 -10
  15. package/dist/config.d.ts +2 -2
  16. package/dist/config.js +10 -11
  17. package/dist/internal/devices.d.ts +2 -2
  18. package/dist/internal/devices.js +39 -49
  19. package/dist/internal/error.d.ts +9 -204
  20. package/dist/internal/error.js +19 -288
  21. package/dist/internal/file_index.d.ts +1 -1
  22. package/dist/internal/file_index.js +9 -9
  23. package/dist/internal/filesystem.d.ts +23 -8
  24. package/dist/internal/index.d.ts +1 -1
  25. package/dist/internal/index.js +1 -1
  26. package/dist/internal/index_fs.d.ts +2 -2
  27. package/dist/internal/index_fs.js +19 -19
  28. package/dist/internal/inode.d.ts +81 -103
  29. package/dist/internal/inode.js +336 -195
  30. package/dist/mixins/async.js +32 -28
  31. package/dist/mixins/mutexed.d.ts +4 -4
  32. package/dist/mixins/mutexed.js +39 -39
  33. package/dist/mixins/readonly.d.ts +2 -2
  34. package/dist/mixins/readonly.js +20 -20
  35. package/dist/mixins/sync.js +2 -2
  36. package/dist/polyfills.js +1 -1
  37. package/dist/readline.js +1 -1
  38. package/dist/utils.d.ts +8 -5
  39. package/dist/utils.js +14 -17
  40. package/dist/vfs/acl.d.ts +8 -8
  41. package/dist/vfs/acl.js +66 -47
  42. package/dist/vfs/async.d.ts +2 -2
  43. package/dist/vfs/async.js +6 -8
  44. package/dist/vfs/dir.d.ts +1 -1
  45. package/dist/vfs/dir.js +3 -4
  46. package/dist/vfs/file.js +33 -24
  47. package/dist/vfs/flags.js +3 -3
  48. package/dist/vfs/ioctl.d.ts +8 -7
  49. package/dist/vfs/ioctl.js +132 -27
  50. package/dist/vfs/promises.d.ts +3 -3
  51. package/dist/vfs/promises.js +200 -235
  52. package/dist/vfs/shared.d.ts +1 -12
  53. package/dist/vfs/shared.js +7 -35
  54. package/dist/vfs/streams.js +9 -9
  55. package/dist/vfs/sync.d.ts +1 -2
  56. package/dist/vfs/sync.js +158 -170
  57. package/dist/vfs/watchers.js +8 -8
  58. package/dist/vfs/xattr.js +89 -106
  59. package/package.json +4 -2
  60. package/scripts/test.js +2 -2
  61. package/tests/assignment.ts +1 -1
  62. package/tests/backend/port.test.ts +4 -4
  63. package/tests/backend/single-buffer.test.ts +39 -10
  64. package/tests/backend/single-buffer.worker.js +30 -0
  65. package/tests/common/context.test.ts +2 -2
  66. package/tests/common/mutex.test.ts +9 -9
  67. package/tests/fetch/fetch.ts +1 -1
  68. package/tests/fs/append.test.ts +4 -4
  69. package/tests/fs/directory.test.ts +25 -25
  70. package/tests/fs/errors.test.ts +15 -19
  71. package/tests/fs/links.test.ts +3 -2
  72. package/tests/fs/open.test.ts +4 -21
  73. package/tests/fs/permissions.test.ts +8 -13
  74. package/tests/fs/read.test.ts +10 -9
  75. package/tests/fs/readFile.test.ts +8 -24
  76. package/tests/fs/rename.test.ts +4 -9
  77. package/tests/fs/stat.test.ts +2 -2
  78. package/tests/fs/times.test.ts +6 -6
  79. package/tests/fs/truncate.test.ts +8 -36
  80. package/tests/fs/watch.test.ts +10 -10
  81. package/tests/fs/write.test.ts +77 -13
  82. package/tests/fs/xattr.test.ts +7 -7
  83. package/tests/logs.js +2 -2
  84. package/tests/setup/port.ts +6 -0
  85. package/dist/internal/log.d.ts +0 -139
  86. package/dist/internal/log.js +0 -219
  87. package/tests/fs/writeFile.test.ts +0 -70
@@ -1,36 +1,32 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import test, { suite } from 'node:test';
3
3
  import { fs } from '../common.js';
4
- import type { ErrnoError } from '../../dist/index.js';
5
4
 
6
5
  const existingFile = '/exit.js';
7
6
 
8
7
  suite('Error messages', () => {
9
8
  const path = '/non-existent';
10
9
 
11
- fs.promises.stat(path).catch((error: ErrnoError) => {
12
- assert.equal(error.bufferSize(), 4 + JSON.stringify(error.toJSON()).length);
13
- });
14
-
15
10
  const missing = { path, code: 'ENOENT' };
16
- const existing = { path: existingFile };
11
+ const existing = { path: existingFile, code: 'EEXIST' };
12
+ const notDir = { path: existingFile, code: 'ENOTDIR' };
17
13
 
18
- test('stat', () => assert.rejects(() => fs.promises.stat(path), missing));
19
- test('mkdir', () => assert.rejects(() => fs.promises.mkdir(existingFile, 0o666), existing));
20
- test('rmdir', () => assert.rejects(() => fs.promises.rmdir(path), missing));
21
- test('rmdir', () => assert.rejects(() => fs.promises.rmdir(existingFile), existing));
22
- test('rename', () => assert.rejects(() => fs.promises.rename(path, 'foo'), missing));
23
- test('open', () => assert.rejects(() => fs.promises.open(path, 'r'), missing));
24
- test('readdir', () => assert.rejects(() => fs.promises.readdir(path), missing));
25
- test('unlink', () => assert.rejects(() => fs.promises.unlink(path), missing));
26
- test('link', () => assert.rejects(() => fs.promises.link(path, 'foo'), missing));
27
- test('chmod', () => assert.rejects(() => fs.promises.chmod(path, 0o666), missing));
28
- test('lstat', () => assert.rejects(() => fs.promises.lstat(path), missing));
29
- test('readlink', () => assert.rejects(() => fs.promises.readlink(path), missing));
14
+ test('stat', async () => await assert.rejects(() => fs.promises.stat(path), missing));
15
+ test('mkdir', async () => await assert.rejects(() => fs.promises.mkdir(existingFile, 0o666), existing));
16
+ test('rmdir (missing)', async () => await assert.rejects(() => fs.promises.rmdir(path), missing));
17
+ test('rmdir (existing)', async () => await assert.rejects(() => fs.promises.rmdir(existingFile), notDir));
18
+ test('rename', async () => await assert.rejects(() => fs.promises.rename(path, 'foo'), missing));
19
+ test('open', async () => await assert.rejects(() => fs.promises.open(path, 'r'), missing));
20
+ test('readdir', async () => await assert.rejects(() => fs.promises.readdir(path), missing));
21
+ test('unlink', async () => await assert.rejects(() => fs.promises.unlink(path), missing));
22
+ test('link', async () => await assert.rejects(() => fs.promises.link(path, 'foo'), missing));
23
+ test('chmod', async () => await assert.rejects(() => fs.promises.chmod(path, 0o666), missing));
24
+ test('lstat', async () => await assert.rejects(() => fs.promises.lstat(path), missing));
25
+ test('readlink', async () => await assert.rejects(() => fs.promises.readlink(path), missing));
30
26
  test('statSync', () => assert.throws(() => fs.statSync(path), missing));
31
27
  test('mkdirSync', () => assert.throws(() => fs.mkdirSync(existingFile, 0o666), existing));
32
28
  test('rmdirSync', () => assert.throws(() => fs.rmdirSync(path), missing));
33
- test('rmdirSync', () => assert.throws(() => fs.rmdirSync(existingFile), existing));
29
+ test('rmdirSync', () => assert.throws(() => fs.rmdirSync(existingFile), notDir));
34
30
  test('renameSync', () => assert.throws(() => fs.renameSync(path, 'foo'), missing));
35
31
  test('openSync', () => assert.throws(() => fs.openSync(path, 'r'), missing));
36
32
  test('readdirSync', () => assert.throws(() => fs.readdirSync(path), missing));
@@ -1,8 +1,8 @@
1
+ import type { Exception } from 'kerium';
1
2
  import assert from 'node:assert/strict';
2
3
  import { suite, test } from 'node:test';
3
4
  import { join } from '../../dist/path.js';
4
5
  import { fs } from '../common.js';
5
- import type { ErrnoError } from '../../dist/index.js';
6
6
 
7
7
  suite('Links', () => {
8
8
  const target = '/a1.js',
@@ -21,6 +21,7 @@ suite('Links', () => {
21
21
  test('readlink', async () => {
22
22
  const destination = await fs.promises.readlink(symlink);
23
23
  assert.equal(destination, target);
24
+ assert.throws(() => fs.readlinkSync(destination));
24
25
  });
25
26
 
26
27
  test('read target contents', async () => {
@@ -59,7 +60,7 @@ suite('Links', () => {
59
60
  });
60
61
 
61
62
  test('link', async t => {
62
- const _ = await fs.promises.link(target, hardlink).catch((e: ErrnoError) => {
63
+ const _ = await fs.promises.link(target, hardlink).catch((e: Exception) => {
63
64
  if (e.code == 'ENOSYS') return e;
64
65
  throw e;
65
66
  });
@@ -1,30 +1,13 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { suite, test } from 'node:test';
3
- import { ErrnoError } from '../../dist/index.js';
4
3
  import { fs } from '../common.js';
5
4
 
6
- suite('fs file opening', () => {
5
+ suite('Opening files', () => {
7
6
  const filename = 'a.js';
8
7
 
9
- test('throw ENOENT when opening non-existent file (sync)', () => {
10
- let caughtException = false;
11
- try {
12
- fs.openSync('/path/to/file/that/does/not/exist', 'r');
13
- } catch (error: any) {
14
- assert(error instanceof ErrnoError);
15
- assert.equal(error?.code, 'ENOENT');
16
- caughtException = true;
17
- }
18
- assert(caughtException);
19
- });
20
-
21
- test('throw ENOENT when opening non-existent file (async)', async () => {
22
- try {
23
- await fs.promises.open('/path/to/file/that/does/not/exist', 'r');
24
- } catch (error: any) {
25
- assert(error instanceof ErrnoError);
26
- assert.equal(error?.code, 'ENOENT');
27
- }
8
+ test('throw ENOENT when opening non-existent file', async () => {
9
+ assert.throws(() => fs.openSync('/path/to/file/that/does/not/exist', 'r'), { code: 'ENOENT' });
10
+ await assert.rejects(fs.promises.open('/path/to/file/that/does/not/exist', 'r'), { code: 'ENOENT' });
28
11
  });
29
12
 
30
13
  test('open file with mode "r"', async () => {
@@ -1,7 +1,7 @@
1
+ import { Exception } from 'kerium';
1
2
  import assert from 'node:assert/strict';
2
3
  import { suite, test } from 'node:test';
3
4
  import { encodeUTF8 } from 'utilium';
4
- import { ErrnoError } from '../../dist/index.js';
5
5
  import { defaultContext } from '../../dist/internal/contexts.js';
6
6
  import { join } from '../../dist/path.js';
7
7
  import { R_OK, W_OK, X_OK } from '../../dist/vfs/constants.js';
@@ -48,19 +48,16 @@ suite('Permissions', () => {
48
48
  });
49
49
 
50
50
  async function test_item(path: string): Promise<void> {
51
- const stats = await fs.promises.stat(path).catch((error: ErrnoError) => {
52
- assert(error instanceof ErrnoError);
51
+ const stats = await fs.promises.stat(path).catch((error: Exception) => {
52
+ assert(error instanceof Exception);
53
53
  assert.equal(error.code, 'EACCES');
54
54
  });
55
- if (!stats) {
56
- return;
57
- }
55
+ if (!stats) return;
58
56
  assert(stats.hasAccess(X_OK));
59
57
 
60
58
  function checkError(access: number) {
61
- return function (error: ErrnoError) {
62
- assert(error instanceof ErrnoError);
63
- assert(error);
59
+ return function (error: Exception) {
60
+ assert(error instanceof Exception);
64
61
  assert(!stats!.hasAccess(access));
65
62
  };
66
63
  }
@@ -80,12 +77,10 @@ suite('Permissions', () => {
80
77
  await fs.promises.unlink(testFile).catch(checkError(W_OK));
81
78
  } else {
82
79
  const handle = await fs.promises.open(path, 'a').catch(checkError(W_OK));
83
- if (!handle) {
84
- return;
85
- }
80
+ if (!handle) return;
86
81
  await handle.close();
87
82
  }
88
- assert(stats.hasAccess(R_OK));
83
+ assert(stats.hasAccess(W_OK));
89
84
  }
90
85
 
91
86
  const copy = { ...defaultContext.credentials };
@@ -1,10 +1,11 @@
1
+ import { Buffer } from 'buffer';
1
2
  import assert from 'node:assert/strict';
2
3
  import { suite, test } from 'node:test';
3
4
  import { fs } from '../common.js';
4
- import { Buffer } from 'buffer';
5
5
 
6
6
  const filepath = 'x.txt';
7
7
  const expected = 'xyz\n';
8
+ const ellipses = '…'.repeat(10_000);
8
9
 
9
10
  suite('read', () => {
10
11
  test('read file asynchronously', async () => {
@@ -22,25 +23,25 @@ suite('read', () => {
22
23
  assert.equal(bytesRead, expected.length);
23
24
  assert.equal(buffer.toString(), expected);
24
25
  });
25
- });
26
26
 
27
- suite('read binary', () => {
28
- test('Read a file and check its binary bytes (asynchronous)', async () => {
27
+ test('Read a file and check its binary bytes asynchronously', async () => {
29
28
  const buff = await fs.promises.readFile('elipses.txt');
29
+ assert.equal(buff.length, 30_000);
30
+ assert.equal(buff.toString(), ellipses);
30
31
  assert.equal((buff[1] << 8) | buff[0], 32994);
31
32
  });
32
33
 
33
- test('Read a file and check its binary bytes (synchronous)', () => {
34
+ test('Read a file and check its binary bytes synchronously', () => {
34
35
  const buff = fs.readFileSync('elipses.txt');
36
+ assert.equal(buff.length, 30_000);
37
+ assert.equal(buff.toString(), ellipses);
35
38
  assert.equal((buff[1] << 8) | buff[0], 32994);
36
39
  });
37
- });
38
40
 
39
- suite('read buffer', () => {
40
41
  const bufferAsync = Buffer.alloc(expected.length);
41
42
  const bufferSync = Buffer.alloc(expected.length);
42
43
 
43
- test('read file asynchronously', async () => {
44
+ test('read file from handle asynchronously', async () => {
44
45
  const handle = await fs.promises.open(filepath, 'r');
45
46
  const { bytesRead } = await handle.read(bufferAsync, 0, expected.length, 0);
46
47
 
@@ -48,7 +49,7 @@ suite('read buffer', () => {
48
49
  assert.equal(bufferAsync.toString(), expected);
49
50
  });
50
51
 
51
- test('read file synchronously', () => {
52
+ test('read file from handle synchronously', () => {
52
53
  const fd = fs.openSync(filepath, 'r');
53
54
  const bytesRead = fs.readSync(fd, bufferSync, 0, expected.length, 0);
54
55
 
@@ -4,7 +4,7 @@ import { fs } from '../common.js';
4
4
 
5
5
  suite('Reading', () => {
6
6
  test('Cannot read a file with an invalid encoding', () => {
7
- assert.throws(() => fs.readFileSync('a.js', 'wrongencoding' as BufferEncoding));
7
+ assert.throws(() => fs.readFileSync('a.js', 'wrong-encoding' as BufferEncoding));
8
8
  });
9
9
 
10
10
  test('Reading past the end of a file should not be an error', async () => {
@@ -12,9 +12,7 @@ suite('Reading', () => {
12
12
  const { bytesRead } = await handle.read(new Uint8Array(10), 0, 10, 10000);
13
13
  assert.equal(bytesRead, 0);
14
14
  });
15
- });
16
15
 
17
- suite('Read and Unlink', () => {
18
16
  const dir = 'test-readfile-unlink';
19
17
  const file = 'test-readfile-unlink/test.bin';
20
18
  const data = new Uint8Array(512).fill(42);
@@ -34,33 +32,19 @@ suite('Read and Unlink', () => {
34
32
  await fs.promises.unlink(file);
35
33
  await fs.promises.rmdir(dir);
36
34
  });
37
- });
38
35
 
39
- suite('Read File', () => {
40
- const fn = 'empty.txt';
41
-
42
- test('read file asynchronously', async () => {
43
- const data: Uint8Array = await fs.promises.readFile(fn);
44
- assert(data != undefined);
45
- });
36
+ const fileName = 'empty.txt';
46
37
 
47
- test('read file with utf-8 encoding asynchronously', async () => {
48
- const data: string = await fs.promises.readFile(fn, 'utf8');
49
- assert.equal(data, '');
38
+ test('read file', async () => {
39
+ assert.equal((await fs.promises.readFile(fileName)).toString(), '');
40
+ assert.equal(fs.readFileSync(fileName).toString(), '');
50
41
  });
51
42
 
52
- test('read file synchronously', () => {
53
- const data: Uint8Array = fs.readFileSync(fn);
54
- assert(data != undefined);
43
+ test('read file with utf-8 encoding', async () => {
44
+ assert.equal(await fs.promises.readFile(fileName, 'utf8'), '');
45
+ assert.equal(fs.readFileSync(fileName, 'utf8'), '');
55
46
  });
56
47
 
57
- test('read file with utf-8 encoding synchronously', () => {
58
- const data: string = fs.readFileSync(fn, 'utf8');
59
- assert.equal(data, '');
60
- });
61
- });
62
-
63
- suite('fs file reading', () => {
64
48
  test('read file synchronously and verify the content', () => {
65
49
  const content = fs.readFileSync('elipses.txt', 'utf8');
66
50
 
@@ -1,6 +1,5 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { suite, test } from 'node:test';
3
- import { ErrnoError } from '../../dist/index.js';
4
3
  import { fs } from '../common.js';
5
4
 
6
5
  suite('Rename', () => {
@@ -77,10 +76,8 @@ suite('Rename', () => {
77
76
  await fs.promises.mkdir(dir);
78
77
  await fs.promises.writeFile(file, 'file contents go here');
79
78
 
80
- await fs.promises.rename(file, dir).catch((error: ErrnoError) => {
81
- assert(error instanceof ErrnoError);
82
- assert.match(error.code, /EISDIR|EPERM/);
83
- });
79
+ await assert.rejects(fs.promises.rename(file, dir), { code: 'EISDIR' });
80
+ assert.throws(() => fs.renameSync(file, dir), { code: 'EISDIR' });
84
81
  });
85
82
 
86
83
  test('rename directory inside itself', async () => {
@@ -89,9 +86,7 @@ suite('Rename', () => {
89
86
 
90
87
  await fs.promises.mkdir(renDir1);
91
88
 
92
- await fs.promises.rename(renDir1, renDir2).catch((error: ErrnoError) => {
93
- assert(error instanceof ErrnoError);
94
- assert.equal(error.code, 'EBUSY');
95
- });
89
+ await assert.rejects(fs.promises.rename(renDir1, renDir2), { code: 'EBUSY' });
90
+ assert.throws(() => fs.renameSync(renDir1, renDir2), { code: 'EBUSY' });
96
91
  });
97
92
  });
@@ -7,8 +7,8 @@ import { fs } from '../common.js';
7
7
  suite('Stats', () => {
8
8
  const existing_file = 'x.txt';
9
9
 
10
- test('stat empty path', () => {
11
- assert.rejects(fs.promises.stat(''));
10
+ test('stat empty path', async () => {
11
+ await assert.rejects(fs.promises.stat(''));
12
12
  });
13
13
 
14
14
  test('stat directory', async () => {
@@ -1,7 +1,7 @@
1
+ import { Exception } from 'kerium';
1
2
  import assert from 'node:assert/strict';
2
3
  import { suite, test } from 'node:test';
3
4
  import { wait } from 'utilium';
4
- import { ErrnoError } from '../../dist/index.js';
5
5
  import type { StatsLike } from '../../dist/vfs/stats.js';
6
6
  import { fs } from '../common.js';
7
7
 
@@ -19,7 +19,7 @@ export function unixTimestamps(stats: StatsLike<number>): Record<'atime' | 'mtim
19
19
  };
20
20
  }
21
21
 
22
- suite('times', () => {
22
+ suite('Times', () => {
23
23
  async function runTest(atime: Date | number, mtime: Date | number): Promise<void> {
24
24
  const times = {
25
25
  atime: typeof atime == 'number' ? Math.floor(atime) : atime.getTime(),
@@ -30,8 +30,8 @@ suite('times', () => {
30
30
 
31
31
  assert.deepEqual(unixTimestamps(await fs.promises.stat(path)), times);
32
32
 
33
- await fs.promises.utimes('foobarbaz', atime, mtime).catch((error: ErrnoError) => {
34
- assert(error instanceof ErrnoError);
33
+ await fs.promises.utimes('foobarbaz', atime, mtime).catch((error: Exception) => {
34
+ assert(error instanceof Exception);
35
35
  assert.equal(error.code, 'ENOENT');
36
36
  });
37
37
 
@@ -46,14 +46,14 @@ suite('times', () => {
46
46
  try {
47
47
  fs.utimesSync('foobarbaz', atime, mtime);
48
48
  } catch (error: any) {
49
- assert(error instanceof ErrnoError);
49
+ assert(error instanceof Exception);
50
50
  assert.equal(error.code, 'ENOENT');
51
51
  }
52
52
 
53
53
  try {
54
54
  fs.futimesSync(-1, atime, mtime);
55
55
  } catch (error: any) {
56
- assert(error instanceof ErrnoError);
56
+ assert(error instanceof Exception);
57
57
  assert.equal(error.code, 'EBADF');
58
58
  }
59
59
  }
@@ -1,94 +1,66 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { suite, test } from 'node:test';
3
3
  import { fs } from '../common.js';
4
- import type { FileHandle } from '../../dist/vfs/promises.js';
5
4
 
6
5
  const path: string = 'truncate-file.txt',
7
6
  size = 1024 * 16,
8
7
  data = new Uint8Array(size).fill('x'.charCodeAt(0));
9
8
 
10
- suite('Truncate, sync', () => {
11
- test('initial write', () => {
9
+ suite('Truncating', () => {
10
+ test('Sync path functions', () => {
12
11
  fs.writeFileSync(path, data);
13
12
  assert.equal(fs.statSync(path).size, size);
14
- });
15
13
 
16
- test('truncate to 1024', () => {
17
14
  fs.truncateSync(path, 1024);
18
15
  assert.equal(fs.statSync(path).size, 1024);
19
- });
20
16
 
21
- test('truncate to 0', () => {
22
17
  fs.truncateSync(path);
23
18
  assert.equal(fs.statSync(path).size, 0);
24
- });
25
19
 
26
- test('write', () => {
27
20
  fs.writeFileSync(path, data);
28
21
  assert.equal(fs.statSync(path).size, size);
29
22
  });
30
23
 
31
- let fd: number;
32
- test('open r+', () => {
33
- fd = fs.openSync(path, 'r+');
34
- });
24
+ test('FD functions', () => {
25
+ const fd = fs.openSync(path, 'r+');
35
26
 
36
- test('ftruncate to 1024', () => {
37
27
  fs.ftruncateSync(fd, 1024);
38
28
  assert.equal(fs.fstatSync(fd).size, 1024);
39
- });
40
29
 
41
- test('ftruncate to 0', () => {
42
30
  fs.ftruncateSync(fd);
43
31
  assert.equal(fs.fstatSync(fd).size, 0);
44
- });
45
32
 
46
- test('close fd', () => {
47
33
  fs.closeSync(fd);
48
34
  });
49
- });
50
- suite('Truncate, async', () => {
35
+
51
36
  const statSize = async (path: string) => (await fs.promises.stat(path)).size;
52
37
 
53
- test('initial write', async () => {
38
+ test('Async path functions', async () => {
54
39
  await fs.promises.writeFile(path, data);
55
40
 
56
41
  assert.equal(await statSize(path), 1024 * 16);
57
- });
58
42
 
59
- test('truncate to 1024', async () => {
60
43
  await fs.promises.truncate(path, 1024);
61
44
  assert.equal(await statSize(path), 1024);
62
- });
63
45
 
64
- test('truncate to 0', async () => {
65
46
  await fs.promises.truncate(path);
66
47
  assert.equal(await statSize(path), 0);
67
- });
68
48
 
69
- test('write', async () => {
70
49
  await fs.promises.writeFile(path, data);
71
50
  assert.equal(await statSize(path), size);
72
51
  });
73
52
 
74
- let handle: FileHandle;
75
- test('open w', async () => {
76
- handle = await fs.promises.open(path, 'w');
77
- });
53
+ test('FileHandle', async () => {
54
+ const handle = await fs.promises.open(path, 'w');
78
55
 
79
- test('handle.truncate to 1024', async () => {
80
56
  await handle.truncate(1024);
81
57
  await handle.sync();
82
58
  assert.equal(await statSize(path), 1024);
83
- });
84
59
 
85
- test('handle.truncate to 0', async () => {
86
60
  await handle.truncate();
87
61
  await handle.sync();
88
62
  assert.equal(await statSize(path), 0);
89
- });
90
63
 
91
- test('close handle', async () => {
92
64
  await handle.close();
93
65
  });
94
66
  });
@@ -11,8 +11,8 @@ await fs.promises.writeFile(testFile, 'Initial content');
11
11
  /**
12
12
  * @todo convert using watcher to void discards pending ES proposal
13
13
  */
14
- await suite('Watch Features', () => {
15
- test('fs.watch should emit events on file change', async () => {
14
+ await suite('Watch', () => {
15
+ test('Events emitted on file change', async () => {
16
16
  const { promise, resolve } = Promise.withResolvers<[string, string]>();
17
17
 
18
18
  using watcher = fs.watch(testFile, (eventType, filename) => {
@@ -27,7 +27,7 @@ await suite('Watch Features', () => {
27
27
  assert.equal(filename, 'test.txt');
28
28
  });
29
29
 
30
- test('fs.watch should emit events on file rename (delete)', async () => {
30
+ test('Events are emitted on delete', async () => {
31
31
  using watcher = fs.watch(testFile, (eventType, filename) => {
32
32
  assert.equal(eventType, 'rename');
33
33
  assert.equal(filename, 'test.txt');
@@ -37,7 +37,7 @@ await suite('Watch Features', () => {
37
37
  await fs.promises.unlink(testFile);
38
38
  });
39
39
 
40
- test('fs.watchFile should detect changes to a file', async () => {
40
+ test('Changes are detected with watchFile()', async () => {
41
41
  const listener = (curr: Stats, prev: Stats) => {
42
42
  assert(curr.mtimeMs != prev.mtimeMs);
43
43
  fs.unwatchFile(testFile, listener);
@@ -49,7 +49,7 @@ await suite('Watch Features', () => {
49
49
  await fs.promises.writeFile(testFile, 'Changed content');
50
50
  });
51
51
 
52
- test('fs.unwatchFile should stop watching the file', async () => {
52
+ test('unwatchFile() works', async () => {
53
53
  let changeDetected = false;
54
54
 
55
55
  const listener = () => {
@@ -66,7 +66,7 @@ await suite('Watch Features', () => {
66
66
  assert(!changeDetected);
67
67
  });
68
68
 
69
- test('fs.watch should work with directories', async () => {
69
+ test('Directories can be watched', async () => {
70
70
  using watcher = fs.watch(testDir, (eventType, filename) => {
71
71
  assert.equal(eventType, 'change');
72
72
  assert.equal(filename, 'newFile.txt');
@@ -75,7 +75,7 @@ await suite('Watch Features', () => {
75
75
  await fs.promises.writeFile(testDir + '/newFile.txt', 'Content');
76
76
  });
77
77
 
78
- test('fs.watch should detect file renames', async () => {
78
+ test('File renames are detected', async () => {
79
79
  const oldFileName = 'oldFile.txt';
80
80
  const newFileName = 'newFile.txt';
81
81
  const oldFile = testDir + '/' + oldFileName;
@@ -102,7 +102,7 @@ await suite('Watch Features', () => {
102
102
  await Promise.all([newFileResolver.promise, oldFileResolver.promise]);
103
103
  });
104
104
 
105
- test('fs.watch should detect file deletions', async () => {
105
+ test('File deletions are detected', async () => {
106
106
  const tempFile = `${testDir}/tempFile.txt`;
107
107
 
108
108
  await fs.promises.writeFile(tempFile, 'Temporary content');
@@ -115,7 +115,7 @@ await suite('Watch Features', () => {
115
115
  await fs.promises.unlink(tempFile);
116
116
  });
117
117
 
118
- test('fs.promises.watch should detect file deletions', async () => {
118
+ test('File deletions are detected by promises API', async () => {
119
119
  const tempFile = `${testDir}/tempFile.txt`;
120
120
 
121
121
  await fs.promises.writeFile(tempFile, 'Temporary content');
@@ -135,7 +135,7 @@ await suite('Watch Features', () => {
135
135
  await promise;
136
136
  });
137
137
 
138
- test('fs.promises.watch should detect file creations recursively', async () => {
138
+ test('File creations are detected recursively', async () => {
139
139
  const subDir = `${testDir}/sub-dir`;
140
140
  const tempFile = `${subDir}/tempFile.txt`;
141
141
  await fs.promises.mkdir(subDir);