| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -495,6 +495,9 @@ the end of the file. | |||
| 495 | 495 | <!-- YAML | |
| 496 | 496 | added: v10.0.0 | |
| 497 | 497 | changes: | |
| 498 | + - version: REPLACEME | ||
| 499 | + pr-url: https://github.com/nodejs/node/pull/37490 | ||
| 500 | + description: The `data` argument supports `AsyncIterable`, `Iterable` and `Stream`. | ||
| 498 | 501 | - version: v14.12.0 | |
| 499 | 502 | pr-url: https://github.com/nodejs/node/pull/34993 | |
| 500 | 503 | description: The `data` parameter will stringify an object with an | |
@@ -505,14 +508,16 @@ changes: | |||
| 505 | 508 | strings anymore. | |
| 506 | 509 | --> | |
| 507 | 510 | ||
| 508 | - * `data` {string|Buffer|Uint8Array|Object} | ||
| 511 | + * `data` {string|Buffer|Uint8Array|Object|AsyncIterable|Iterable | ||
| 512 | + |Stream} | ||
| 509 | 513 | * `options` {Object|string} | |
| 510 | 514 | * `encoding` {string|null} The expected character encoding when `data` is a | |
| 511 | 515 | string. **Default:** `'utf8'` | |
| 512 | 516 | * Returns: {Promise} | |
| 513 | 517 | ||
| 514 | 518 | Asynchronously writes data to a file, replacing the file if it already exists. | |
| 515 | - `data` can be a string, a buffer, or an object with an own `toString` function | ||
| 519 | + `data` can be a string, a buffer, an {AsyncIterable} or {Iterable} object, or an | ||
| 520 | + object with an own `toString` function | ||
| 516 | 521 | property. The promise is resolved with no arguments upon success. | |
| 517 | 522 | ||
| 518 | 523 | If `options` is a string, then it specifies the `encoding`. | |
@@ -1236,7 +1241,7 @@ added: v10.0.0 | |||
| 1236 | 1241 | changes: | |
| 1237 | 1242 | - version: REPLACEME | |
| 1238 | 1243 | pr-url: https://github.com/nodejs/node/pull/37490 | |
| 1239 | - description: The `data` argument supports `AsyncIterable`, `Iterable` & `Stream`. | ||
| 1244 | + description: The `data` argument supports `AsyncIterable`, `Iterable` and `Stream`. | ||
| 1240 | 1245 | - version: v14.17.0 | |
| 1241 | 1246 | pr-url: https://github.com/nodejs/node/pull/35993 | |
| 1242 | 1247 | description: The options argument may include an AbortSignal to abort an | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,6 +9,7 @@ const common = require('../common'); | |||
| 9 | 9 | const fs = require('fs'); | |
| 10 | 10 | const { open, writeFile } = fs.promises; | |
| 11 | 11 | const path = require('path'); | |
| 12 | + const { Readable } = require('stream'); | ||
| 12 | 13 | const tmpdir = require('../common/tmpdir'); | |
| 13 | 14 | const assert = require('assert'); | |
| 14 | 15 | const tmpDir = tmpdir.path; | |
@@ -18,13 +19,15 @@ tmpdir.refresh(); | |||
| 18 | 19 | async function validateWriteFile() { | |
| 19 | 20 | const filePathForHandle = path.resolve(tmpDir, 'tmp-write-file2.txt'); | |
| 20 | 21 | const fileHandle = await open(filePathForHandle, 'w+'); | |
| 21 | - const buffer = Buffer.from('Hello world'.repeat(100), 'utf8'); | ||
| 22 | + try { | ||
| 23 | + const buffer = Buffer.from('Hello world'.repeat(100), 'utf8'); | ||
| 22 | 24 | ||
| 23 | - await fileHandle.writeFile(buffer); | ||
| 24 | - const readFileData = fs.readFileSync(filePathForHandle); | ||
| 25 | - assert.deepStrictEqual(buffer, readFileData); | ||
| 26 | - | ||
| 27 | - await fileHandle.close(); | ||
| 25 | + await fileHandle.writeFile(buffer); | ||
| 26 | + const readFileData = fs.readFileSync(filePathForHandle); | ||
| 27 | + assert.deepStrictEqual(buffer, readFileData); | ||
| 28 | + } finally { | ||
| 29 | + await fileHandle.close(); | ||
| 30 | + } | ||
| 28 | 31 | } | |
| 29 | 32 | ||
| 30 | 33 | // Signal aborted while writing file | |
@@ -40,6 +43,155 @@ async function doWriteAndCancel() { | |||
| 40 | 43 | }); | |
| 41 | 44 | } | |
| 42 | 45 | ||
| 43 | - validateWriteFile() | ||
| 44 | - .then(doWriteAndCancel) | ||
| 45 | - .then(common.mustCall()); | ||
| 46 | + const dest = path.resolve(tmpDir, 'tmp.txt'); | ||
| 47 | + const otherDest = path.resolve(tmpDir, 'tmp-2.txt'); | ||
| 48 | + const stream = Readable.from(['a', 'b', 'c']); | ||
| 49 | + const stream2 = Readable.from(['ümlaut', ' ', 'sechzig']); | ||
| 50 | + const iterable = { | ||
| 51 | + expected: 'abc', | ||
| 52 | + *[Symbol.iterator]() { | ||
| 53 | + yield 'a'; | ||
| 54 | + yield 'b'; | ||
| 55 | + yield 'c'; | ||
| 56 | + } | ||
| 57 | + }; | ||
| 58 | + function iterableWith(value) { | ||
| 59 | + return { | ||
| 60 | + *[Symbol.iterator]() { | ||
| 61 | + yield value; | ||
| 62 | + } | ||
| 63 | + }; | ||
| 64 | + } | ||
| 65 | + const bufferIterable = { | ||
| 66 | + expected: 'abc', | ||
| 67 | + *[Symbol.iterator]() { | ||
| 68 | + yield Buffer.from('a'); | ||
| 69 | + yield Buffer.from('b'); | ||
| 70 | + yield Buffer.from('c'); | ||
| 71 | + } | ||
| 72 | + }; | ||
| 73 | + const asyncIterable = { | ||
| 74 | + expected: 'abc', | ||
| 75 | + async* [Symbol.asyncIterator]() { | ||
| 76 | + yield 'a'; | ||
| 77 | + yield 'b'; | ||
| 78 | + yield 'c'; | ||
| 79 | + } | ||
| 80 | + }; | ||
| 81 | + | ||
| 82 | + async function doWriteStream() { | ||
| 83 | + const fileHandle = await open(dest, 'w+'); | ||
| 84 | + try { | ||
| 85 | + await fileHandle.writeFile(stream); | ||
| 86 | + const expected = 'abc'; | ||
| 87 | + const data = fs.readFileSync(dest, 'utf-8'); | ||
| 88 | + assert.deepStrictEqual(data, expected); | ||
| 89 | + } finally { | ||
| 90 | + await fileHandle.close(); | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + async function doWriteStreamWithCancel() { | ||
| 95 | + const controller = new AbortController(); | ||
| 96 | + const { signal } = controller; | ||
| 97 | + process.nextTick(() => controller.abort()); | ||
| 98 | + const fileHandle = await open(otherDest, 'w+'); | ||
| 99 | + try { | ||
| 100 | + await assert.rejects( | ||
| 101 | + fileHandle.writeFile(stream, { signal }), | ||
| 102 | + { name: 'AbortError' } | ||
| 103 | + ); | ||
| 104 | + } finally { | ||
| 105 | + await fileHandle.close(); | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + async function doWriteIterable() { | ||
| 110 | + const fileHandle = await open(dest, 'w+'); | ||
| 111 | + try { | ||
| 112 | + await fileHandle.writeFile(iterable); | ||
| 113 | + const data = fs.readFileSync(dest, 'utf-8'); | ||
| 114 | + assert.deepStrictEqual(data, iterable.expected); | ||
| 115 | + } finally { | ||
| 116 | + await fileHandle.close(); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + async function doWriteInvalidIterable() { | ||
| 121 | + const fileHandle = await open(dest, 'w+'); | ||
| 122 | + try { | ||
| 123 | + await Promise.all( | ||
| 124 | + [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) => | ||
| 125 | + assert.rejects( | ||
| 126 | + fileHandle.writeFile(iterableWith(value)), | ||
| 127 | + { code: 'ERR_INVALID_ARG_TYPE' } | ||
| 128 | + ) | ||
| 129 | + ) | ||
| 130 | + ); | ||
| 131 | + } finally { | ||
| 132 | + await fileHandle.close(); | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + async function doWriteIterableWithEncoding() { | ||
| 137 | + const fileHandle = await open(dest, 'w+'); | ||
| 138 | + try { | ||
| 139 | + await fileHandle.writeFile(stream2, 'latin1'); | ||
| 140 | + const expected = 'ümlaut sechzig'; | ||
| 141 | + const data = fs.readFileSync(dest, 'latin1'); | ||
| 142 | + assert.deepStrictEqual(data, expected); | ||
| 143 | + } finally { | ||
| 144 | + await fileHandle.close(); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + async function doWriteBufferIterable() { | ||
| 149 | + const fileHandle = await open(dest, 'w+'); | ||
| 150 | + try { | ||
| 151 | + await fileHandle.writeFile(bufferIterable); | ||
| 152 | + const data = fs.readFileSync(dest, 'utf-8'); | ||
| 153 | + assert.deepStrictEqual(data, bufferIterable.expected); | ||
| 154 | + } finally { | ||
| 155 | + await fileHandle.close(); | ||
| 156 | + } | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + async function doWriteAsyncIterable() { | ||
| 160 | + const fileHandle = await open(dest, 'w+'); | ||
| 161 | + try { | ||
| 162 | + await fileHandle.writeFile(asyncIterable); | ||
| 163 | + const data = fs.readFileSync(dest, 'utf-8'); | ||
| 164 | + assert.deepStrictEqual(data, asyncIterable.expected); | ||
| 165 | + } finally { | ||
| 166 | + await fileHandle.close(); | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + async function doWriteInvalidValues() { | ||
| 171 | + const fileHandle = await open(dest, 'w+'); | ||
| 172 | + try { | ||
| 173 | + await Promise.all( | ||
| 174 | + [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) => | ||
| 175 | + assert.rejects( | ||
| 176 | + fileHandle.writeFile(value), | ||
| 177 | + { code: 'ERR_INVALID_ARG_TYPE' } | ||
| 178 | + ) | ||
| 179 | + ) | ||
| 180 | + ); | ||
| 181 | + } finally { | ||
| 182 | + await fileHandle.close(); | ||
| 183 | + } | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + (async () => { | ||
| 187 | + await validateWriteFile(); | ||
| 188 | + await doWriteAndCancel(); | ||
| 189 | + await doWriteStream(); | ||
| 190 | + await doWriteStreamWithCancel(); | ||
| 191 | + await doWriteIterable(); | ||
| 192 | + await doWriteInvalidIterable(); | ||
| 193 | + await doWriteIterableWithEncoding(); | ||
| 194 | + await doWriteBufferIterable(); | ||
| 195 | + await doWriteAsyncIterable(); | ||
| 196 | + await doWriteInvalidValues(); | ||
| 197 | + })().then(common.mustCall()); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -67,9 +67,10 @@ async function doWriteStreamWithCancel() { | |||
| 67 | 67 | const controller = new AbortController(); | |
| 68 | 68 | const { signal } = controller; | |
| 69 | 69 | process.nextTick(() => controller.abort()); | |
| 70 | - assert.rejects(fsPromises.writeFile(otherDest, stream, { signal }), { | ||
| 71 | - name: 'AbortError' | ||
| 72 | - }); | ||
| 70 | + await assert.rejects( | ||
| 71 | + fsPromises.writeFile(otherDest, stream, { signal }), | ||
| 72 | + { name: 'AbortError' } | ||
| 73 | + ); | ||
| 73 | 74 | } | |
| 74 | 75 | ||
| 75 | 76 | async function doWriteIterable() { | |
@@ -121,9 +122,10 @@ async function doWriteWithCancel() { | |||
| 121 | 122 | const controller = new AbortController(); | |
| 122 | 123 | const { signal } = controller; | |
| 123 | 124 | process.nextTick(() => controller.abort()); | |
| 124 | - assert.rejects(fsPromises.writeFile(otherDest, buffer, { signal }), { | ||
| 125 | - name: 'AbortError' | ||
| 126 | - }); | ||
| 125 | + await assert.rejects( | ||
| 126 | + fsPromises.writeFile(otherDest, buffer, { signal }), | ||
| 127 | + { name: 'AbortError' } | ||
| 128 | + ); | ||
| 127 | 129 | } | |
| 128 | 130 | ||
| 129 | 131 | async function doAppend() { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments