Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine du Hamel <duhamelantoine1995@gmail.com>2021-08-21 18:13:42 +0300
committerAntoine du Hamel <duhamelantoine1995@gmail.com>2021-08-30 01:45:37 +0300
commit52abf271c563ddffdc93b444ea05e5347a7f2784 (patch)
treeb27cc363bbc47e1576792c409ddaffbb6e38a6dd
parent6fdd5827f0956ffc4e7ffe31babaf530e42f75b9 (diff)
fs: add docs and tests for `AsyncIterable` support in `fh.writeFile`
Refs: https://github.com/nodejs/node/pull/37490 PR-URL: https://github.com/nodejs/node/pull/39836 Reviewed-By: Nitzan Uziely <linkgoron@gmail.com>
-rw-r--r--doc/api/fs.md11
-rw-r--r--test/parallel/test-fs-promises-file-handle-writeFile.js170
-rw-r--r--test/parallel/test-fs-promises-writefile.js14
3 files changed, 177 insertions, 18 deletions
diff --git a/doc/api/fs.md b/doc/api/fs.md
index 687ece15f01..f41ebdf56ce 100644
--- a/doc/api/fs.md
+++ b/doc/api/fs.md
@@ -545,6 +545,9 @@ the end of the file.
<!-- YAML
added: v10.0.0
changes:
+ - version: v15.14.0
+ pr-url: https://github.com/nodejs/node/pull/37490
+ description: The `data` argument supports `AsyncIterable`, `Iterable` and `Stream`.
- version: v14.12.0
pr-url: https://github.com/nodejs/node/pull/34993
description: The `data` parameter will stringify an object with an
@@ -555,14 +558,16 @@ changes:
strings anymore.
-->
-* `data` {string|Buffer|TypedArray|DataView|Object}
+* `data` {string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable
+ |Stream}
* `options` {Object|string}
* `encoding` {string|null} The expected character encoding when `data` is a
string. **Default:** `'utf8'`
* Returns: {Promise}
Asynchronously writes data to a file, replacing the file if it already exists.
-`data` can be a string, a buffer, or an object with an own `toString` function
+`data` can be a string, a buffer, an {AsyncIterable} or {Iterable} object, or an
+object with an own `toString` function
property. The promise is resolved with no arguments upon success.
If `options` is a string, then it specifies the `encoding`.
@@ -1341,7 +1346,7 @@ added: v10.0.0
changes:
- version: v15.14.0
pr-url: https://github.com/nodejs/node/pull/37490
- description: The `data` argument supports `AsyncIterable`, `Iterable` & `Stream`.
+ description: The `data` argument supports `AsyncIterable`, `Iterable` and `Stream`.
- version: v15.2.0
pr-url: https://github.com/nodejs/node/pull/35993
description: The options argument may include an AbortSignal to abort an
diff --git a/test/parallel/test-fs-promises-file-handle-writeFile.js b/test/parallel/test-fs-promises-file-handle-writeFile.js
index 44f049f55a9..2c1a80e4f52 100644
--- a/test/parallel/test-fs-promises-file-handle-writeFile.js
+++ b/test/parallel/test-fs-promises-file-handle-writeFile.js
@@ -8,6 +8,7 @@ const common = require('../common');
const fs = require('fs');
const { open, writeFile } = fs.promises;
const path = require('path');
+const { Readable } = require('stream');
const tmpdir = require('../common/tmpdir');
const assert = require('assert');
const tmpDir = tmpdir.path;
@@ -17,13 +18,15 @@ tmpdir.refresh();
async function validateWriteFile() {
const filePathForHandle = path.resolve(tmpDir, 'tmp-write-file2.txt');
const fileHandle = await open(filePathForHandle, 'w+');
- const buffer = Buffer.from('Hello world'.repeat(100), 'utf8');
-
- await fileHandle.writeFile(buffer);
- const readFileData = fs.readFileSync(filePathForHandle);
- assert.deepStrictEqual(buffer, readFileData);
+ try {
+ const buffer = Buffer.from('Hello world'.repeat(100), 'utf8');
- await fileHandle.close();
+ await fileHandle.writeFile(buffer);
+ const readFileData = fs.readFileSync(filePathForHandle);
+ assert.deepStrictEqual(buffer, readFileData);
+ } finally {
+ await fileHandle.close();
+ }
}
// Signal aborted while writing file
@@ -43,6 +46,155 @@ async function doWriteAndCancel() {
}
}
-validateWriteFile()
- .then(doWriteAndCancel)
- .then(common.mustCall());
+const dest = path.resolve(tmpDir, 'tmp.txt');
+const otherDest = path.resolve(tmpDir, 'tmp-2.txt');
+const stream = Readable.from(['a', 'b', 'c']);
+const stream2 = Readable.from(['ümlaut', ' ', 'sechzig']);
+const iterable = {
+ expected: 'abc',
+ *[Symbol.iterator]() {
+ yield 'a';
+ yield 'b';
+ yield 'c';
+ }
+};
+function iterableWith(value) {
+ return {
+ *[Symbol.iterator]() {
+ yield value;
+ }
+ };
+}
+const bufferIterable = {
+ expected: 'abc',
+ *[Symbol.iterator]() {
+ yield Buffer.from('a');
+ yield Buffer.from('b');
+ yield Buffer.from('c');
+ }
+};
+const asyncIterable = {
+ expected: 'abc',
+ async* [Symbol.asyncIterator]() {
+ yield 'a';
+ yield 'b';
+ yield 'c';
+ }
+};
+
+async function doWriteStream() {
+ const fileHandle = await open(dest, 'w+');
+ try {
+ await fileHandle.writeFile(stream);
+ const expected = 'abc';
+ const data = fs.readFileSync(dest, 'utf-8');
+ assert.deepStrictEqual(data, expected);
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+async function doWriteStreamWithCancel() {
+ const controller = new AbortController();
+ const { signal } = controller;
+ process.nextTick(() => controller.abort());
+ const fileHandle = await open(otherDest, 'w+');
+ try {
+ await assert.rejects(
+ fileHandle.writeFile(stream, { signal }),
+ { name: 'AbortError' }
+ );
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+async function doWriteIterable() {
+ const fileHandle = await open(dest, 'w+');
+ try {
+ await fileHandle.writeFile(iterable);
+ const data = fs.readFileSync(dest, 'utf-8');
+ assert.deepStrictEqual(data, iterable.expected);
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+async function doWriteInvalidIterable() {
+ const fileHandle = await open(dest, 'w+');
+ try {
+ await Promise.all(
+ [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) =>
+ assert.rejects(
+ fileHandle.writeFile(iterableWith(value)),
+ { code: 'ERR_INVALID_ARG_TYPE' }
+ )
+ )
+ );
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+async function doWriteIterableWithEncoding() {
+ const fileHandle = await open(dest, 'w+');
+ try {
+ await fileHandle.writeFile(stream2, 'latin1');
+ const expected = 'ümlaut sechzig';
+ const data = fs.readFileSync(dest, 'latin1');
+ assert.deepStrictEqual(data, expected);
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+async function doWriteBufferIterable() {
+ const fileHandle = await open(dest, 'w+');
+ try {
+ await fileHandle.writeFile(bufferIterable);
+ const data = fs.readFileSync(dest, 'utf-8');
+ assert.deepStrictEqual(data, bufferIterable.expected);
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+async function doWriteAsyncIterable() {
+ const fileHandle = await open(dest, 'w+');
+ try {
+ await fileHandle.writeFile(asyncIterable);
+ const data = fs.readFileSync(dest, 'utf-8');
+ assert.deepStrictEqual(data, asyncIterable.expected);
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+async function doWriteInvalidValues() {
+ const fileHandle = await open(dest, 'w+');
+ try {
+ await Promise.all(
+ [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) =>
+ assert.rejects(
+ fileHandle.writeFile(value),
+ { code: 'ERR_INVALID_ARG_TYPE' }
+ )
+ )
+ );
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+(async () => {
+ await validateWriteFile();
+ await doWriteAndCancel();
+ await doWriteStream();
+ await doWriteStreamWithCancel();
+ await doWriteIterable();
+ await doWriteInvalidIterable();
+ await doWriteIterableWithEncoding();
+ await doWriteBufferIterable();
+ await doWriteAsyncIterable();
+ await doWriteInvalidValues();
+})().then(common.mustCall());
diff --git a/test/parallel/test-fs-promises-writefile.js b/test/parallel/test-fs-promises-writefile.js
index 494a9015773..25df61b2b48 100644
--- a/test/parallel/test-fs-promises-writefile.js
+++ b/test/parallel/test-fs-promises-writefile.js
@@ -74,9 +74,10 @@ async function doWriteStreamWithCancel() {
const controller = new AbortController();
const { signal } = controller;
process.nextTick(() => controller.abort());
- assert.rejects(fsPromises.writeFile(otherDest, stream, { signal }), {
- name: 'AbortError'
- });
+ await assert.rejects(
+ fsPromises.writeFile(otherDest, stream, { signal }),
+ { name: 'AbortError' }
+ );
}
async function doWriteIterable() {
@@ -134,9 +135,10 @@ async function doWriteWithCancel() {
const controller = new AbortController();
const { signal } = controller;
process.nextTick(() => controller.abort());
- assert.rejects(fsPromises.writeFile(otherDest, buffer, { signal }), {
- name: 'AbortError'
- });
+ await assert.rejects(
+ fsPromises.writeFile(otherDest, buffer, { signal }),
+ { name: 'AbortError' }
+ );
}
async function doAppend() {