fs: add support for async iterators to `fsPromises.writeFile` · nodejs/node@b6f4901
@@ -7,20 +7,115 @@ const path = require('path');
77const tmpdir = require('../common/tmpdir');
88const assert = require('assert');
99const tmpDir = tmpdir.path;
10+const { Readable } = require('stream');
10111112tmpdir.refresh();
12131314const dest = path.resolve(tmpDir, 'tmp.txt');
1415const otherDest = path.resolve(tmpDir, 'tmp-2.txt');
1516const buffer = Buffer.from('abc'.repeat(1000));
1617const buffer2 = Buffer.from('xyz'.repeat(1000));
18+const stream = Readable.from(['a', 'b', 'c']);
19+const stream2 = Readable.from(['ümlaut', ' ', 'sechzig']);
20+const iterable = {
21+expected: 'abc',
22+*[Symbol.iterator]() {
23+yield 'a';
24+yield 'b';
25+yield 'c';
26+}
27+};
28+function iterableWith(value) {
29+return {
30+*[Symbol.iterator]() {
31+yield value;
32+}
33+};
34+}
35+const bufferIterable = {
36+expected: 'abc',
37+*[Symbol.iterator]() {
38+yield Buffer.from('a');
39+yield Buffer.from('b');
40+yield Buffer.from('c');
41+}
42+};
43+const asyncIterable = {
44+expected: 'abc',
45+async* [Symbol.asyncIterator]() {
46+yield 'a';
47+yield 'b';
48+yield 'c';
49+}
50+};
17511852async function doWrite() {
1953await fsPromises.writeFile(dest, buffer);
2054const data = fs.readFileSync(dest);
2155assert.deepStrictEqual(data, buffer);
2256}
235758+async function doWriteStream() {
59+await fsPromises.writeFile(dest, stream);
60+const expected = 'abc';
61+const data = fs.readFileSync(dest, 'utf-8');
62+assert.deepStrictEqual(data, expected);
63+}
64+65+async function doWriteStreamWithCancel() {
66+const controller = new AbortController();
67+const { signal } = controller;
68+process.nextTick(() => controller.abort());
69+assert.rejects(fsPromises.writeFile(otherDest, stream, { signal }), {
70+name: 'AbortError'
71+});
72+}
73+74+async function doWriteIterable() {
75+await fsPromises.writeFile(dest, iterable);
76+const data = fs.readFileSync(dest, 'utf-8');
77+assert.deepStrictEqual(data, iterable.expected);
78+}
79+80+async function doWriteInvalidIterable() {
81+await Promise.all(
82+[42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) =>
83+assert.rejects(fsPromises.writeFile(dest, iterableWith(value)), {
84+code: 'ERR_INVALID_ARG_TYPE',
85+})
86+)
87+);
88+}
89+90+async function doWriteIterableWithEncoding() {
91+await fsPromises.writeFile(dest, stream2, 'latin1');
92+const expected = 'ümlaut sechzig';
93+const data = fs.readFileSync(dest, 'latin1');
94+assert.deepStrictEqual(data, expected);
95+}
96+97+async function doWriteBufferIterable() {
98+await fsPromises.writeFile(dest, bufferIterable);
99+const data = fs.readFileSync(dest, 'utf-8');
100+assert.deepStrictEqual(data, bufferIterable.expected);
101+}
102+103+async function doWriteAsyncIterable() {
104+await fsPromises.writeFile(dest, asyncIterable);
105+const data = fs.readFileSync(dest, 'utf-8');
106+assert.deepStrictEqual(data, asyncIterable.expected);
107+}
108+109+async function doWriteInvalidValues() {
110+await Promise.all(
111+[42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) =>
112+assert.rejects(fsPromises.writeFile(dest, value), {
113+code: 'ERR_INVALID_ARG_TYPE',
114+})
115+)
116+);
117+}
118+24119async function doWriteWithCancel() {
25120const controller = new AbortController();
26121const { signal } = controller;
@@ -50,9 +145,18 @@ async function doReadWithEncoding() {
50145assert.deepStrictEqual(data, syncData);
51146}
5214753-doWrite()
54-.then(doWriteWithCancel)
55-.then(doAppend)
56-.then(doRead)
57-.then(doReadWithEncoding)
58-.then(common.mustCall());
148+(async () => {
149+await doWrite();
150+await doWriteWithCancel();
151+await doAppend();
152+await doRead();
153+await doReadWithEncoding();
154+await doWriteStream();
155+await doWriteStreamWithCancel();
156+await doWriteIterable();
157+await doWriteInvalidIterable();
158+await doWriteIterableWithEncoding();
159+await doWriteBufferIterable();
160+await doWriteAsyncIterable();
161+await doWriteInvalidValues();
162+})().then(common.mustCall());