1'use strict'; 2 3const common = require('../common'); 4const fs = require('fs'); 5const fsPromises = fs.promises; 6const path = require('path'); 7const tmpdir = require('../common/tmpdir'); 8const assert = require('assert'); 9const tmpDir = tmpdir.path; 10const { Readable } = require('stream'); 11 12tmpdir.refresh(); 13 14const dest = path.resolve(tmpDir, 'tmp.txt'); 15const otherDest = path.resolve(tmpDir, 'tmp-2.txt'); 16const buffer = Buffer.from('abc'.repeat(1000)); 17const buffer2 = Buffer.from('xyz'.repeat(1000)); 18const stream = Readable.from(['a', 'b', 'c']); 19const stream2 = Readable.from(['ümlaut', ' ', 'sechzig']); 20const iterable = { 21 expected: 'abc', 22 *[Symbol.iterator]() { 23 yield 'a'; 24 yield 'b'; 25 yield 'c'; 26 } 27}; 28 29const veryLargeBuffer = { 30 expected: 'dogs running'.repeat(512 * 1024), 31 *[Symbol.iterator]() { 32 yield Buffer.from('dogs running'.repeat(512 * 1024), 'utf8'); 33 } 34}; 35 36function iterableWith(value) { 37 return { 38 *[Symbol.iterator]() { 39 yield value; 40 } 41 }; 42} 43const bufferIterable = { 44 expected: 'abc', 45 *[Symbol.iterator]() { 46 yield Buffer.from('a'); 47 yield Buffer.from('b'); 48 yield Buffer.from('c'); 49 } 50}; 51const asyncIterable = { 52 expected: 'abc', 53 async* [Symbol.asyncIterator]() { 54 yield 'a'; 55 yield 'b'; 56 yield 'c'; 57 } 58}; 59 60async function doWrite() { 61 await fsPromises.writeFile(dest, buffer); 62 const data = fs.readFileSync(dest); 63 assert.deepStrictEqual(data, buffer); 64} 65 66async function doWriteStream() { 67 await fsPromises.writeFile(dest, stream); 68 const expected = 'abc'; 69 const data = fs.readFileSync(dest, 'utf-8'); 70 assert.deepStrictEqual(data, expected); 71} 72 73async function doWriteStreamWithCancel() { 74 const controller = new AbortController(); 75 const { signal } = controller; 76 process.nextTick(() => controller.abort()); 77 await assert.rejects( 78 fsPromises.writeFile(otherDest, stream, { signal }), 79 { name: 'AbortError' } 80 ); 81} 82 83async function doWriteIterable() { 84 await fsPromises.writeFile(dest, iterable); 85 const data = fs.readFileSync(dest, 'utf-8'); 86 assert.deepStrictEqual(data, iterable.expected); 87} 88 89async function doWriteInvalidIterable() { 90 await Promise.all( 91 [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) => 92 assert.rejects(fsPromises.writeFile(dest, iterableWith(value)), { 93 code: 'ERR_INVALID_ARG_TYPE', 94 }) 95 ) 96 ); 97} 98 99async function doWriteIterableWithEncoding() { 100 await fsPromises.writeFile(dest, stream2, 'latin1'); 101 const expected = 'ümlaut sechzig'; 102 const data = fs.readFileSync(dest, 'latin1'); 103 assert.deepStrictEqual(data, expected); 104} 105 106async function doWriteBufferIterable() { 107 await fsPromises.writeFile(dest, bufferIterable); 108 const data = fs.readFileSync(dest, 'utf-8'); 109 assert.deepStrictEqual(data, bufferIterable.expected); 110} 111 112async function doWriteAsyncIterable() { 113 await fsPromises.writeFile(dest, asyncIterable); 114 const data = fs.readFileSync(dest, 'utf-8'); 115 assert.deepStrictEqual(data, asyncIterable.expected); 116} 117 118async function doWriteAsyncLargeIterable() { 119 await fsPromises.writeFile(dest, veryLargeBuffer); 120 const data = fs.readFileSync(dest, 'utf-8'); 121 assert.deepStrictEqual(data, veryLargeBuffer.expected); 122} 123 124async function doWriteInvalidValues() { 125 await Promise.all( 126 [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) => 127 assert.rejects(fsPromises.writeFile(dest, value), { 128 code: 'ERR_INVALID_ARG_TYPE', 129 }) 130 ) 131 ); 132} 133 134async function doWriteWithCancel() { 135 const controller = new AbortController(); 136 const { signal } = controller; 137 process.nextTick(() => controller.abort()); 138 await assert.rejects( 139 fsPromises.writeFile(otherDest, buffer, { signal }), 140 { name: 'AbortError' } 141 ); 142} 143 144async function doAppend() { 145 await fsPromises.appendFile(dest, buffer2, { flag: null }); 146 const data = fs.readFileSync(dest); 147 const buf = Buffer.concat([buffer, buffer2]); 148 assert.deepStrictEqual(buf, data); 149} 150 151async function doRead() { 152 const data = await fsPromises.readFile(dest); 153 const buf = fs.readFileSync(dest); 154 assert.deepStrictEqual(buf, data); 155} 156 157async function doReadWithEncoding() { 158 const data = await fsPromises.readFile(dest, 'utf-8'); 159 const syncData = fs.readFileSync(dest, 'utf-8'); 160 assert.strictEqual(typeof data, 'string'); 161 assert.deepStrictEqual(data, syncData); 162} 163 164(async () => { 165 await doWrite(); 166 await doWriteWithCancel(); 167 await doAppend(); 168 await doRead(); 169 await doReadWithEncoding(); 170 await doWriteStream(); 171 await doWriteStreamWithCancel(); 172 await doWriteIterable(); 173 await doWriteInvalidIterable(); 174 await doWriteIterableWithEncoding(); 175 await doWriteBufferIterable(); 176 await doWriteAsyncIterable(); 177 await doWriteAsyncLargeIterable(); 178 await doWriteInvalidValues(); 179})().then(common.mustCall()); 180