@zenfs/core 2.5.8 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/backends/cow.d.ts +17 -0
  2. package/dist/backends/cow.js +72 -25
  3. package/dist/backends/fetch.d.ts +4 -0
  4. package/dist/backends/fetch.js +7 -3
  5. package/dist/backends/single_buffer.d.ts +2 -2
  6. package/dist/backends/store/fs.d.ts +6 -6
  7. package/dist/backends/store/fs.js +10 -2
  8. package/dist/internal/devices.d.ts +6 -6
  9. package/dist/internal/index_fs.d.ts +4 -4
  10. package/dist/node/async.js +1 -1
  11. package/dist/node/dir.d.ts +3 -1
  12. package/dist/node/dir.js +23 -5
  13. package/dist/node/promises.d.ts +3 -1
  14. package/dist/node/promises.js +128 -89
  15. package/dist/node/streams.d.ts +4 -0
  16. package/dist/node/streams.js +9 -10
  17. package/dist/node/sync.js +71 -40
  18. package/dist/utils.d.ts +8 -1
  19. package/dist/utils.js +26 -7
  20. package/dist/vfs/async.js +224 -85
  21. package/dist/vfs/file.d.ts +13 -7
  22. package/dist/vfs/file.js +661 -357
  23. package/dist/vfs/shared.d.ts +1 -0
  24. package/dist/vfs/shared.js +18 -1
  25. package/dist/vfs/sync.js +214 -85
  26. package/dist/vfs/vcache.d.ts +66 -0
  27. package/dist/vfs/vcache.js +249 -0
  28. package/dist/vfs/vnode.d.ts +72 -0
  29. package/dist/vfs/vnode.js +215 -0
  30. package/dist/vfs/watchers.js +4 -2
  31. package/dist/vfs/xattr.js +2 -2
  32. package/eslint.shared.js +1 -1
  33. package/package.json +3 -3
  34. package/scripts/make-index.js +43 -16
  35. package/scripts/test.js +28 -21
  36. package/tests/backend/fetch.test.ts +24 -1
  37. package/tests/backend/port.test.ts +3 -3
  38. package/tests/backend/store.test.ts +49 -0
  39. package/tests/common.ts +60 -0
  40. package/tests/fetch/fetch.ts +6 -0
  41. package/tests/fetch/run.sh +2 -2
  42. package/tests/fetch/server.js +3 -3
  43. package/tests/fs/append.test.ts +5 -5
  44. package/tests/fs/concurrency.test.ts +90 -0
  45. package/tests/fs/dir.test.ts +13 -15
  46. package/tests/fs/directory.test.ts +32 -31
  47. package/tests/fs/errors.test.ts +151 -31
  48. package/tests/fs/exists.test.ts +4 -4
  49. package/tests/fs/links.test.ts +4 -11
  50. package/tests/fs/open.test.ts +4 -4
  51. package/tests/fs/permissions.test.ts +15 -15
  52. package/tests/fs/read.test.ts +9 -9
  53. package/tests/fs/readFile.test.ts +9 -9
  54. package/tests/fs/rename.test.ts +8 -8
  55. package/tests/fs/scaling.test.ts +4 -4
  56. package/tests/fs/stat.test.ts +20 -20
  57. package/tests/fs/streams.test.ts +9 -6
  58. package/tests/fs/tempdir.test.ts +33 -10
  59. package/tests/fs/times.test.ts +11 -11
  60. package/tests/fs/truncate.test.ts +6 -6
  61. package/tests/fs/watch.test.ts +107 -53
  62. package/tests/fs/write.test.ts +10 -10
  63. package/tests/fs/xattr.test.ts +3 -3
  64. package/tests/native/run.sh +3 -0
  65. package/tests/native/setup.ts +230 -0
  66. package/types/readable-stream.d.ts +2 -2
@@ -1,14 +1,14 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
2
  import assert from 'node:assert/strict';
3
3
  import { suite, test } from 'node:test';
4
- import { fs } from '../common.js';
4
+ import { config, fs } from '../common.js';
5
5
 
6
6
  suite('Reading', () => {
7
- test('Cannot read a file with an invalid encoding', () => {
7
+ test('Cannot read a file with an invalid encoding', config('sync'), () => {
8
8
  assert.throws(() => fs.readFileSync('a.js', 'wrong-encoding' as BufferEncoding));
9
9
  });
10
10
 
11
- test('Reading past the end of a file should not be an error', async () => {
11
+ test('Reading past the end of a file should not be an error', config('async'), async () => {
12
12
  const handle = await fs.promises.open('a.js', 'r');
13
13
  const { bytesRead } = await handle.read(new Uint8Array(10), 0, 10, 10000);
14
14
  assert.equal(bytesRead, 0);
@@ -18,35 +18,35 @@ suite('Reading', () => {
18
18
  const file = 'test-readfile-unlink/test.bin';
19
19
  const data = new Uint8Array(512).fill(42);
20
20
 
21
- test('create directory and write file', async () => {
21
+ test('create directory and write file', config('async', 'write', 'directories'), async () => {
22
22
  await fs.promises.mkdir(dir);
23
23
  await fs.promises.writeFile(file, data);
24
24
  });
25
25
 
26
- test('read file and verify its content', async () => {
26
+ test('read file and verify its content', config('async'), async () => {
27
27
  const read: Uint8Array = await fs.promises.readFile(file);
28
28
  assert.equal(read.length, data.length);
29
29
  assert.equal(read[0], 42);
30
30
  });
31
31
 
32
- test('unlink file and remove directory', async () => {
32
+ test('unlink file and remove directory', config('async', 'write', 'directories'), async () => {
33
33
  await fs.promises.unlink(file);
34
34
  await fs.promises.rmdir(dir);
35
35
  });
36
36
 
37
37
  const fileName = 'empty.txt';
38
38
 
39
- test('read file', async () => {
39
+ test('read file', config('sync', 'async'), async () => {
40
40
  assert.equal((await fs.promises.readFile(fileName)).toString(), '');
41
41
  assert.equal(fs.readFileSync(fileName).toString(), '');
42
42
  });
43
43
 
44
- test('read file with utf-8 encoding', async () => {
44
+ test('read file with utf-8 encoding', config('sync', 'async'), async () => {
45
45
  assert.equal(await fs.promises.readFile(fileName, 'utf8'), '');
46
46
  assert.equal(fs.readFileSync(fileName, 'utf8'), '');
47
47
  });
48
48
 
49
- test('read file synchronously and verify the content', () => {
49
+ test('read file synchronously and verify the content', config('sync'), () => {
50
50
  const content = fs.readFileSync('elipses.txt', 'utf8');
51
51
 
52
52
  assert.equal(content.length, 10000);
@@ -1,9 +1,9 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
2
  import assert from 'node:assert/strict';
3
3
  import { suite, test } from 'node:test';
4
- import { fs } from '../common.js';
4
+ import { config, fs } from '../common.js';
5
5
 
6
- suite('Rename', () => {
6
+ suite('Rename', config('rename'), () => {
7
7
  /**
8
8
  * Creates the following directory structure within `dir`:
9
9
  * - _rename_me
@@ -30,7 +30,7 @@ suite('Rename', () => {
30
30
  assert(await fs.promises.exists(dir + '/_rename_me/lol.txt'));
31
31
  }
32
32
 
33
- test('rename directory', async () => {
33
+ test('rename directory', config('async'), async () => {
34
34
  const oldDir = '/rename_test';
35
35
  const newDir = '/rename_test2';
36
36
 
@@ -53,7 +53,7 @@ suite('Rename', () => {
53
53
  await fs.promises.rename(oldDir, newDir + '/newDir');
54
54
  });
55
55
 
56
- test('rename file', async () => {
56
+ test('rename file', config('async'), async () => {
57
57
  const dir = '/rename_file_test';
58
58
  const one = dir + '/fun.js';
59
59
  const two = dir + '/fun2.js';
@@ -70,7 +70,7 @@ suite('Rename', () => {
70
70
  assert(!(await fs.promises.exists(one)));
71
71
  });
72
72
 
73
- test('File to Directory and Directory to File Rename', async () => {
73
+ test('File to Directory and Directory to File Rename', config('sync', 'async'), async () => {
74
74
  const dir = '/rename_file_dir_test';
75
75
  const file = '/rename_file_dir_test.txt';
76
76
 
@@ -81,13 +81,13 @@ suite('Rename', () => {
81
81
  assert.throws(() => fs.renameSync(file, dir), { code: 'EISDIR' });
82
82
  });
83
83
 
84
- test('rename directory inside itself', async () => {
84
+ test('rename directory inside itself', config('sync', 'async'), async () => {
85
85
  const renDir1 = '/rename_dir_1';
86
86
  const renDir2 = '/rename_dir_1/lol';
87
87
 
88
88
  await fs.promises.mkdir(renDir1);
89
89
 
90
- await assert.rejects(fs.promises.rename(renDir1, renDir2), { code: 'EBUSY' });
91
- assert.throws(() => fs.renameSync(renDir1, renDir2), { code: 'EBUSY' });
90
+ await assert.rejects(fs.promises.rename(renDir1, renDir2), { code: 'EINVAL' });
91
+ assert.throws(() => fs.renameSync(renDir1, renDir2), { code: 'EINVAL' });
92
92
  });
93
93
  });
@@ -2,14 +2,14 @@
2
2
  import { sync } from '@zenfs/core';
3
3
  import assert from 'node:assert/strict';
4
4
  import { suite, test } from 'node:test';
5
- import { fs } from '../common.js';
5
+ import { config, fs } from '../common.js';
6
6
 
7
7
  const n_files = 130;
8
8
  const huge_size = 0x1000000;
9
9
 
10
10
  // Tests for having a lot of various things (number of inodes/files, individual file size, etc.).
11
- suite('Scaling', () => {
12
- test('Lots of inodes/files', async () => {
11
+ suite('Scaling', config('write'), () => {
12
+ test('Lots of inodes/files', config('sync', 'async'), async () => {
13
13
  fs.mkdirSync('/n');
14
14
 
15
15
  for (let i = 0; i < n_files; i++) {
@@ -28,7 +28,7 @@ suite('Scaling', () => {
28
28
  await Promise.all(results);
29
29
  });
30
30
 
31
- test('Singular file size', () => {
31
+ test('Singular file size', config('sync'), () => {
32
32
  fs.writeFileSync('/huge', new Uint8Array(huge_size));
33
33
  assert.equal(fs.statSync('/huge').size, huge_size);
34
34
  });
@@ -1,41 +1,41 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
- import { defaultContext, Stats } from '@zenfs/core';
2
+ import { defaultContext, hasAccess } from '@zenfs/core';
3
3
  import assert from 'node:assert/strict';
4
4
  import { suite, test } from 'node:test';
5
- import { fs } from '../common.js';
5
+ import { config, fs } from '../common.js';
6
6
 
7
7
  suite('Stats', () => {
8
8
  const existing_file = 'x.txt';
9
9
 
10
- test('stat empty path', async () => {
10
+ test('stat empty path', config('async'), async () => {
11
11
  await assert.rejects(fs.promises.stat(''));
12
12
  });
13
13
 
14
- test('stat directory', async () => {
14
+ test('stat directory', config('async'), async () => {
15
15
  const stats = await fs.promises.stat('/');
16
- assert(stats instanceof Stats);
16
+ assert(stats instanceof fs.Stats);
17
17
  });
18
18
 
19
- test('lstat directory', async () => {
19
+ test('lstat directory', config('async'), async () => {
20
20
  const stats = await fs.promises.lstat('/');
21
- assert(stats instanceof Stats);
21
+ assert(stats instanceof fs.Stats);
22
22
  });
23
23
 
24
- test('FileHandle.stat', async () => {
24
+ test('FileHandle.stat', config('async'), async () => {
25
25
  const handle = await fs.promises.open(existing_file, 'r');
26
26
  const stats = await handle.stat();
27
- assert(stats instanceof Stats);
27
+ assert(stats instanceof fs.Stats);
28
28
  await handle.close();
29
29
  });
30
30
 
31
- test('fstatSync file', () => {
31
+ test('fstatSync file', config('sync'), () => {
32
32
  const fd = fs.openSync(existing_file, 'r');
33
33
  const stats = fs.fstatSync(fd);
34
- assert(stats instanceof Stats);
34
+ assert(stats instanceof fs.Stats);
35
35
  fs.close(fd);
36
36
  });
37
37
 
38
- test('hasAccess for non-root access', () => {
38
+ test('hasAccess for non-root access', config('sync', 'permissions'), () => {
39
39
  const newFile = 'new.txt';
40
40
 
41
41
  fs.writeFileSync(newFile, 'hello', { mode: 0o640 });
@@ -58,21 +58,21 @@ suite('Stats', () => {
58
58
 
59
59
  assert.equal(stat.gid, nonRootCredentials.gid);
60
60
  assert.equal(stat.uid, 0);
61
- assert.equal(stat.hasAccess(fs.constants.R_OK), true);
62
- assert.equal(stat.hasAccess(fs.constants.W_OK), false);
63
- assert.equal(stat.hasAccess(fs.constants.X_OK), false);
61
+ assert.equal(hasAccess(defaultContext, stat, fs.constants.R_OK), true);
62
+ assert.equal(hasAccess(defaultContext, stat, fs.constants.W_OK), false);
63
+ assert.equal(hasAccess(defaultContext, stat, fs.constants.X_OK), false);
64
64
  // changing group
65
65
 
66
66
  Object.assign(defaultContext.credentials, { ...nonRootCredentials, gid: 44 });
67
67
 
68
- assert.equal(stat.hasAccess(fs.constants.R_OK), false);
69
- assert.equal(stat.hasAccess(fs.constants.W_OK), false);
70
- assert.equal(stat.hasAccess(fs.constants.X_OK), false);
68
+ assert.equal(hasAccess(defaultContext, stat, fs.constants.R_OK), false);
69
+ assert.equal(hasAccess(defaultContext, stat, fs.constants.W_OK), false);
70
+ assert.equal(hasAccess(defaultContext, stat, fs.constants.X_OK), false);
71
71
 
72
72
  Object.assign(defaultContext.credentials, prevCredentials);
73
73
  });
74
74
 
75
- test('stat file', async () => {
75
+ test('stat file', config('async'), async () => {
76
76
  const stats = await fs.promises.stat(existing_file);
77
77
  assert(!stats.isDirectory());
78
78
  assert(stats.isFile());
@@ -81,6 +81,6 @@ suite('Stats', () => {
81
81
  assert(!stats.isCharacterDevice());
82
82
  assert(!stats.isFIFO());
83
83
  assert(!stats.isSymbolicLink());
84
- assert(stats instanceof Stats);
84
+ assert(stats instanceof fs.Stats);
85
85
  });
86
86
  });
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
2
  import assert from 'node:assert/strict';
3
3
  import { suite, test } from 'node:test';
4
- import { fs } from '../common.js';
4
+ import { config, fs } from '../common.js';
5
5
 
6
6
  // Top-level initialization
7
7
  const testFilePath = 'test-file.txt';
@@ -11,7 +11,7 @@ await fs.promises.writeFile(testFilePath, testData);
11
11
  const testFilePathWrite = 'test-file-write.txt';
12
12
  await fs.promises.writeFile(testFilePathWrite, ''); // Ensure the file exists
13
13
 
14
- suite('Streams', () => {
14
+ suite('Streams', config('streams'), () => {
15
15
  test('ReadStream reads data correctly', (_, done) => {
16
16
  const readStream = fs.createReadStream(testFilePath);
17
17
 
@@ -36,8 +36,9 @@ suite('Streams', () => {
36
36
  closed = true;
37
37
  });
38
38
 
39
+ // Closing before the stream has finished reading is a premature close
39
40
  readStream.close(err => {
40
- assert.ifError(err);
41
+ assert.equal((err as NodeJS.ErrnoException | null)?.code, 'ERR_STREAM_PREMATURE_CLOSE');
41
42
  assert(closed);
42
43
  done();
43
44
  });
@@ -81,7 +82,7 @@ suite('Streams', () => {
81
82
  test('createReadStream with end', async () => {
82
83
  await fs.promises.writeFile('hello.txt', 'Hello world');
83
84
 
84
- const stream = fs.createReadStream('hello.txt', { end: 5, encoding: 'utf-8' });
85
+ const stream = fs.createReadStream('hello.txt', { end: 4, encoding: 'utf-8' });
85
86
 
86
87
  const data = (await stream.toArray()).join('');
87
88
 
@@ -130,12 +131,14 @@ suite('Streams', () => {
130
131
  test('FileHandle.createReadStream after close should give an error', async () => {
131
132
  const fileHandle = await fs.promises.open(testFilePath, 'r');
132
133
  await fileHandle.close();
133
- assert.throws(() => fileHandle.createReadStream(), { code: 'EBADF' });
134
+ // Closing invalidates the descriptor, so it fails range validation
135
+ assert.throws(() => fileHandle.createReadStream(), { code: 'ERR_OUT_OF_RANGE' });
134
136
  });
135
137
 
136
138
  test('FileHandle.createWriteStream after close should give an error', async () => {
137
139
  const fileHandle = await fs.promises.open(testFilePathWrite, 'w');
138
140
  await fileHandle.close();
139
- assert.throws(() => fileHandle.createWriteStream(), { code: 'EBADF' });
141
+ // Closing invalidates the descriptor, so it fails range validation
142
+ assert.throws(() => fileHandle.createWriteStream(), { code: 'ERR_OUT_OF_RANGE' });
140
143
  });
141
144
  });
@@ -1,41 +1,64 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
2
  import { test, suite } from 'node:test';
3
- import { fs } from '../common.js';
3
+ import { config, fs } from '../common.js';
4
4
  import assert from 'node:assert/strict';
5
5
  import { basename } from 'node:path/posix';
6
6
 
7
7
  await fs.promises.mkdir('/tmp');
8
8
 
9
- suite('Temporary Directories', () => {
10
- test('mkdtempSync', () => {
11
- const path = fs.mkdtempSync('test-', { encoding: 'utf8' });
9
+ suite('Temporary Directories', config('tempdir'), () => {
10
+ test('mkdtempSync', config('sync'), () => {
11
+ const path = fs.mkdtempSync('/tmp/test-', { encoding: 'utf8' });
12
12
 
13
13
  assert.deepEqual(fs.readdirSync('/tmp'), [basename(path)]);
14
14
 
15
15
  fs.rmdirSync(path);
16
16
  });
17
17
 
18
- test('mkdtemp', async () => {
19
- const path = await fs.promises.mkdtemp('test-', { encoding: 'utf8' });
18
+ test('mkdtemp', config('async'), async () => {
19
+ const path = await fs.promises.mkdtemp('/tmp/test-', { encoding: 'utf8' });
20
20
 
21
21
  assert.deepEqual(await fs.promises.readdir('/tmp'), [basename(path)]);
22
22
 
23
23
  await fs.promises.rmdir(path);
24
24
  });
25
25
 
26
- test('mkdtempDisposableSync', () => {
27
- using result = fs.mkdtempDisposableSync('test-', { encoding: 'utf8' });
26
+ test('mkdtempDisposableSync', config('sync'), () => {
27
+ using result = fs.mkdtempDisposableSync('/tmp/test-', { encoding: 'utf8' });
28
28
 
29
29
  assert.deepEqual(fs.readdirSync('/tmp'), [basename(result.path)]);
30
30
 
31
31
  fs.rmdirSync(result.path);
32
32
  });
33
33
 
34
- test('mkdtempDisposable', async () => {
35
- await using result = await fs.promises.mkdtempDisposable('test-', { encoding: 'utf8' });
34
+ test('mkdtempDisposable', config('async'), async () => {
35
+ await using result = await fs.promises.mkdtempDisposable('/tmp/test-', { encoding: 'utf8' });
36
36
 
37
37
  assert.deepEqual(await fs.promises.readdir('/tmp'), [basename(result.path)]);
38
38
 
39
39
  await fs.promises.rmdir(result.path);
40
40
  });
41
+
42
+ /* A relative prefix is resolved against the working directory, rather than always being placed in `/tmp`.
43
+ Note the returned path keeps the prefix it was given, so it is only compared by basename here. */
44
+
45
+ test('mkdtempSync with a relative prefix', config('sync'), () => {
46
+ const path = fs.mkdtempSync('tmp/relative-', { encoding: 'utf8' });
47
+
48
+ assert(basename(path).startsWith('relative-'));
49
+ assert(fs.statSync(path).isDirectory());
50
+ assert(fs.readdirSync('/tmp').includes(basename(path)));
51
+
52
+ fs.rmdirSync(path);
53
+ });
54
+
55
+ test('mkdtemp with a relative prefix', config('async'), async () => {
56
+ const path = await fs.promises.mkdtemp('tmp/relative-', { encoding: 'utf8' });
57
+
58
+ assert(basename(path).startsWith('relative-'));
59
+ assert((await fs.promises.stat(path)).isDirectory());
60
+ assert((await fs.promises.readdir('/tmp')).includes(basename(path)));
61
+
62
+ await fs.promises.rmdir(path);
63
+ });
41
64
  });
@@ -1,10 +1,10 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
2
  import type { StatsLike } from '@zenfs/core';
3
- import { Exception } from 'kerium';
3
+ import type { Exception } from 'kerium';
4
4
  import assert from 'node:assert/strict';
5
5
  import { suite, test } from 'node:test';
6
6
  import { wait } from 'utilium';
7
- import { fs } from '../common.js';
7
+ import { config, fs } from '../common.js';
8
8
 
9
9
  const path = 'x.txt';
10
10
 
@@ -20,11 +20,12 @@ export function unixTimestamps(stats: StatsLike<number>): Record<'atime' | 'mtim
20
20
  };
21
21
  }
22
22
 
23
- suite('Times', () => {
23
+ suite('Times', config('times'), () => {
24
24
  async function runTest(atime: Date | number, mtime: Date | number): Promise<void> {
25
+ // Numbers are seconds since the epoch, while `Date`s and stats are in milliseconds
25
26
  const times = {
26
- atime: typeof atime == 'number' ? Math.floor(atime) : atime.getTime(),
27
- mtime: typeof mtime == 'number' ? Math.floor(mtime) : mtime.getTime(),
27
+ atime: typeof atime == 'number' ? Math.floor(atime * 1000) : atime.getTime(),
28
+ mtime: typeof mtime == 'number' ? Math.floor(mtime * 1000) : mtime.getTime(),
28
29
  };
29
30
 
30
31
  await fs.promises.utimes(path, atime, mtime);
@@ -32,7 +33,7 @@ suite('Times', () => {
32
33
  assert.deepEqual(unixTimestamps(await fs.promises.stat(path)), times);
33
34
 
34
35
  await fs.promises.utimes('foobarbaz', atime, mtime).catch((error: Exception) => {
35
- assert(error instanceof Exception);
36
+ assert(error instanceof Error);
36
37
  assert.equal(error.code, 'ENOENT');
37
38
  });
38
39
 
@@ -47,15 +48,14 @@ suite('Times', () => {
47
48
  try {
48
49
  fs.utimesSync('foobarbaz', atime, mtime);
49
50
  } catch (error: any) {
50
- assert(error instanceof Exception);
51
51
  assert.equal(error.code, 'ENOENT');
52
52
  }
53
53
 
54
54
  try {
55
55
  fs.futimesSync(-1, atime, mtime);
56
56
  } catch (error: any) {
57
- assert(error instanceof Exception);
58
- assert.equal(error.code, 'EBADF');
57
+ // A negative descriptor fails range validation before it is looked up
58
+ assert.equal(error.code, 'ERR_OUT_OF_RANGE');
59
59
  }
60
60
  }
61
61
 
@@ -67,7 +67,7 @@ suite('Times', () => {
67
67
  await test('from stats', () => runTest(stats.atime, stats.mtime));
68
68
  });
69
69
 
70
- test('read changes atime', async () => {
70
+ test('read changes atime', config('sync'), async () => {
71
71
  const before = fs.statSync(path).atimeMs;
72
72
  fs.readFileSync(path);
73
73
  await wait(25);
@@ -75,7 +75,7 @@ suite('Times', () => {
75
75
  assert(before < after);
76
76
  });
77
77
 
78
- test('write changes mtime', async () => {
78
+ test('write changes mtime', config('sync', 'write'), async () => {
79
79
  const before = fs.statSync(path).mtimeMs;
80
80
  fs.writeFileSync(path, 'cool');
81
81
  await wait(25);
@@ -1,14 +1,14 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-or-later
2
2
  import assert from 'node:assert/strict';
3
3
  import { suite, test } from 'node:test';
4
- import { fs } from '../common.js';
4
+ import { config, fs } from '../common.js';
5
5
 
6
6
  const path: string = 'truncate-file.txt',
7
7
  size = 1024 * 16,
8
8
  data = new Uint8Array(size).fill('x'.charCodeAt(0));
9
9
 
10
- suite('Truncating', () => {
11
- test('Sync path functions', () => {
10
+ suite('Truncating', config('truncate'), () => {
11
+ test('Sync path functions', config('sync'), () => {
12
12
  fs.writeFileSync(path, data);
13
13
  assert.equal(fs.statSync(path).size, size);
14
14
 
@@ -22,7 +22,7 @@ suite('Truncating', () => {
22
22
  assert.equal(fs.statSync(path).size, size);
23
23
  });
24
24
 
25
- test('FD functions', () => {
25
+ test('FD functions', config('sync'), () => {
26
26
  const fd = fs.openSync(path, 'r+');
27
27
 
28
28
  fs.ftruncateSync(fd, 1024);
@@ -36,7 +36,7 @@ suite('Truncating', () => {
36
36
 
37
37
  const statSize = async (path: string) => (await fs.promises.stat(path)).size;
38
38
 
39
- test('Async path functions', async () => {
39
+ test('Async path functions', config('async'), async () => {
40
40
  await fs.promises.writeFile(path, data);
41
41
 
42
42
  assert.equal(await statSize(path), 1024 * 16);
@@ -51,7 +51,7 @@ suite('Truncating', () => {
51
51
  assert.equal(await statSize(path), size);
52
52
  });
53
53
 
54
- test('FileHandle', async () => {
54
+ test('FileHandle', config('async'), async () => {
55
55
  const handle = await fs.promises.open(path, 'w');
56
56
 
57
57
  await handle.truncate(1024);