mirror of
https://github.com/nodejs/node.git
synced 2025-12-28 07:50:41 +00:00
fs: add flush option to appendFile() functions
This commit adds documentation and tests for the 'flush' option of the fs.appendFile family of functions. Technically, support was indirectly added in #50009, but this makes it more official. Refs: https://github.com/nodejs/node/issues/49886 Refs: https://github.com/nodejs/node/pull/50009 PR-URL: https://github.com/nodejs/node/pull/50095 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
09f80a9f64
commit
f971106072
@ -180,6 +180,9 @@ longer be used.
|
||||
<!-- YAML
|
||||
added: v10.0.0
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/50095
|
||||
description: The `flush` option is now supported.
|
||||
- version:
|
||||
- v15.14.0
|
||||
- v14.18.0
|
||||
@ -194,6 +197,8 @@ changes:
|
||||
* `data` {string|Buffer|TypedArray|DataView|AsyncIterable|Iterable|Stream}
|
||||
* `options` {Object|string}
|
||||
* `encoding` {string|null} **Default:** `'utf8'`
|
||||
* `flush` {boolean} If `true`, the underlying file descriptor is flushed
|
||||
prior to closing it. **Default:** `false`.
|
||||
* Returns: {Promise} Fulfills with `undefined` upon success.
|
||||
|
||||
Alias of [`filehandle.writeFile()`][].
|
||||
@ -896,6 +901,10 @@ the error raised if the file is not accessible.
|
||||
|
||||
<!-- YAML
|
||||
added: v10.0.0
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/50095
|
||||
description: The `flush` option is now supported.
|
||||
-->
|
||||
|
||||
* `path` {string|Buffer|URL|FileHandle} filename or {FileHandle}
|
||||
@ -904,6 +913,8 @@ added: v10.0.0
|
||||
* `encoding` {string|null} **Default:** `'utf8'`
|
||||
* `mode` {integer} **Default:** `0o666`
|
||||
* `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`.
|
||||
* `flush` {boolean} If `true`, the underlying file descriptor is flushed
|
||||
prior to closing it. **Default:** `false`.
|
||||
* Returns: {Promise} Fulfills with `undefined` upon success.
|
||||
|
||||
Asynchronously append data to a file, creating the file if it does not yet
|
||||
@ -2052,6 +2063,9 @@ the user from reading or writing to it.
|
||||
<!-- YAML
|
||||
added: v0.6.7
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/50095
|
||||
description: The `flush` option is now supported.
|
||||
- version: v18.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/41678
|
||||
description: Passing an invalid callback to the `callback` argument
|
||||
@ -2079,6 +2093,8 @@ changes:
|
||||
* `encoding` {string|null} **Default:** `'utf8'`
|
||||
* `mode` {integer} **Default:** `0o666`
|
||||
* `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`.
|
||||
* `flush` {boolean} If `true`, the underlying file descriptor is flushed
|
||||
prior to closing it. **Default:** `false`.
|
||||
* `callback` {Function}
|
||||
* `err` {Error}
|
||||
|
||||
@ -5142,6 +5158,9 @@ try {
|
||||
<!-- YAML
|
||||
added: v0.6.7
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/50095
|
||||
description: The `flush` option is now supported.
|
||||
- version: v7.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/7831
|
||||
description: The passed `options` object will never be modified.
|
||||
@ -5156,6 +5175,8 @@ changes:
|
||||
* `encoding` {string|null} **Default:** `'utf8'`
|
||||
* `mode` {integer} **Default:** `0o666`
|
||||
* `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`.
|
||||
* `flush` {boolean} If `true`, the underlying file descriptor is flushed
|
||||
prior to closing it. **Default:** `false`.
|
||||
|
||||
Synchronously append data to a file, creating the file if it does not yet
|
||||
exist. `data` can be a string or a {Buffer}.
|
||||
|
||||
114
test/parallel/test-fs-append-file-flush.js
Normal file
114
test/parallel/test-fs-append-file-flush.js
Normal file
@ -0,0 +1,114 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const assert = require('node:assert');
|
||||
const fs = require('node:fs');
|
||||
const fsp = require('node:fs/promises');
|
||||
const test = require('node:test');
|
||||
const data = 'foo';
|
||||
let cnt = 0;
|
||||
|
||||
function nextFile() {
|
||||
return tmpdir.resolve(`${cnt++}.out`);
|
||||
}
|
||||
|
||||
tmpdir.refresh();
|
||||
|
||||
test('synchronous version', async (t) => {
|
||||
await t.test('validation', (t) => {
|
||||
for (const v of ['true', '', 0, 1, [], {}, Symbol()]) {
|
||||
assert.throws(() => {
|
||||
fs.appendFileSync(nextFile(), data, { flush: v });
|
||||
}, { code: 'ERR_INVALID_ARG_TYPE' });
|
||||
}
|
||||
});
|
||||
|
||||
await t.test('performs flush', (t) => {
|
||||
const spy = t.mock.method(fs, 'fsyncSync');
|
||||
const file = nextFile();
|
||||
fs.appendFileSync(file, data, { flush: true });
|
||||
const calls = spy.mock.calls;
|
||||
assert.strictEqual(calls.length, 1);
|
||||
assert.strictEqual(calls[0].result, undefined);
|
||||
assert.strictEqual(calls[0].error, undefined);
|
||||
assert.strictEqual(calls[0].arguments.length, 1);
|
||||
assert.strictEqual(typeof calls[0].arguments[0], 'number');
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), data);
|
||||
});
|
||||
|
||||
await t.test('does not perform flush', (t) => {
|
||||
const spy = t.mock.method(fs, 'fsyncSync');
|
||||
|
||||
for (const v of [undefined, null, false]) {
|
||||
const file = nextFile();
|
||||
fs.appendFileSync(file, data, { flush: v });
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), data);
|
||||
}
|
||||
|
||||
assert.strictEqual(spy.mock.calls.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
test('callback version', async (t) => {
|
||||
await t.test('validation', (t) => {
|
||||
for (const v of ['true', '', 0, 1, [], {}, Symbol()]) {
|
||||
assert.throws(() => {
|
||||
fs.appendFileSync(nextFile(), data, { flush: v });
|
||||
}, { code: 'ERR_INVALID_ARG_TYPE' });
|
||||
}
|
||||
});
|
||||
|
||||
await t.test('performs flush', (t, done) => {
|
||||
const spy = t.mock.method(fs, 'fsync');
|
||||
const file = nextFile();
|
||||
fs.appendFile(file, data, { flush: true }, common.mustSucceed(() => {
|
||||
const calls = spy.mock.calls;
|
||||
assert.strictEqual(calls.length, 1);
|
||||
assert.strictEqual(calls[0].result, undefined);
|
||||
assert.strictEqual(calls[0].error, undefined);
|
||||
assert.strictEqual(calls[0].arguments.length, 2);
|
||||
assert.strictEqual(typeof calls[0].arguments[0], 'number');
|
||||
assert.strictEqual(typeof calls[0].arguments[1], 'function');
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), data);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
await t.test('does not perform flush', (t, done) => {
|
||||
const values = [undefined, null, false];
|
||||
const spy = t.mock.method(fs, 'fsync');
|
||||
let cnt = 0;
|
||||
|
||||
for (const v of values) {
|
||||
const file = nextFile();
|
||||
|
||||
fs.appendFile(file, data, { flush: v }, common.mustSucceed(() => {
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), data);
|
||||
cnt++;
|
||||
|
||||
if (cnt === values.length) {
|
||||
assert.strictEqual(spy.mock.calls.length, 0);
|
||||
done();
|
||||
}
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('promise based version', async (t) => {
|
||||
await t.test('validation', async (t) => {
|
||||
for (const v of ['true', '', 0, 1, [], {}, Symbol()]) {
|
||||
await assert.rejects(() => {
|
||||
return fsp.appendFile(nextFile(), data, { flush: v });
|
||||
}, { code: 'ERR_INVALID_ARG_TYPE' });
|
||||
}
|
||||
});
|
||||
|
||||
await t.test('success path', async (t) => {
|
||||
for (const v of [undefined, null, false, true]) {
|
||||
const file = nextFile();
|
||||
await fsp.appendFile(file, data, { flush: v });
|
||||
assert.strictEqual(await fsp.readFile(file, 'utf8'), data);
|
||||
}
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user