• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4
5// The following tests validate base functionality for the fs.promises
6// FileHandle.writeFile method.
7
8const fs = require('fs');
9const { open, writeFile } = fs.promises;
10const path = require('path');
11const { Readable } = require('stream');
12const tmpdir = require('../common/tmpdir');
13const assert = require('assert');
14const tmpDir = tmpdir.path;
15
16tmpdir.refresh();
17
18async function validateWriteFile() {
19  const filePathForHandle = path.resolve(tmpDir, 'tmp-write-file2.txt');
20  const fileHandle = await open(filePathForHandle, 'w+');
21  try {
22    const buffer = Buffer.from('Hello world'.repeat(100), 'utf8');
23
24    await fileHandle.writeFile(buffer);
25    const readFileData = fs.readFileSync(filePathForHandle);
26    assert.deepStrictEqual(buffer, readFileData);
27  } finally {
28    await fileHandle.close();
29  }
30}
31
32// Signal aborted while writing file
33async function doWriteAndCancel() {
34  const filePathForHandle = path.resolve(tmpDir, 'dogs-running.txt');
35  const fileHandle = await open(filePathForHandle, 'w+');
36  try {
37    const buffer = Buffer.from('dogs running'.repeat(512 * 1024), 'utf8');
38    const controller = new AbortController();
39    const { signal } = controller;
40    process.nextTick(() => controller.abort());
41    await assert.rejects(writeFile(fileHandle, buffer, { signal }), {
42      name: 'AbortError'
43    });
44  } finally {
45    await fileHandle.close();
46  }
47}
48
49const dest = path.resolve(tmpDir, 'tmp.txt');
50const otherDest = path.resolve(tmpDir, 'tmp-2.txt');
51const stream = Readable.from(['a', 'b', 'c']);
52const stream2 = Readable.from(['ümlaut', ' ', 'sechzig']);
53const iterable = {
54  expected: 'abc',
55  *[Symbol.iterator]() {
56    yield 'a';
57    yield 'b';
58    yield 'c';
59  }
60};
61function iterableWith(value) {
62  return {
63    *[Symbol.iterator]() {
64      yield value;
65    }
66  };
67}
68const bufferIterable = {
69  expected: 'abc',
70  *[Symbol.iterator]() {
71    yield Buffer.from('a');
72    yield Buffer.from('b');
73    yield Buffer.from('c');
74  }
75};
76const asyncIterable = {
77  expected: 'abc',
78  async* [Symbol.asyncIterator]() {
79    yield 'a';
80    yield 'b';
81    yield 'c';
82  }
83};
84
85async function doWriteStream() {
86  const fileHandle = await open(dest, 'w+');
87  try {
88    await fileHandle.writeFile(stream);
89    const expected = 'abc';
90    const data = fs.readFileSync(dest, 'utf-8');
91    assert.deepStrictEqual(data, expected);
92  } finally {
93    await fileHandle.close();
94  }
95}
96
97async function doWriteStreamWithCancel() {
98  const controller = new AbortController();
99  const { signal } = controller;
100  process.nextTick(() => controller.abort());
101  const fileHandle = await open(otherDest, 'w+');
102  try {
103    await assert.rejects(
104      fileHandle.writeFile(stream, { signal }),
105      { name: 'AbortError' }
106    );
107  } finally {
108    await fileHandle.close();
109  }
110}
111
112async function doWriteIterable() {
113  const fileHandle = await open(dest, 'w+');
114  try {
115    await fileHandle.writeFile(iterable);
116    const data = fs.readFileSync(dest, 'utf-8');
117    assert.deepStrictEqual(data, iterable.expected);
118  } finally {
119    await fileHandle.close();
120  }
121}
122
123async function doWriteInvalidIterable() {
124  const fileHandle = await open(dest, 'w+');
125  try {
126    await Promise.all(
127      [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) =>
128        assert.rejects(
129          fileHandle.writeFile(iterableWith(value)),
130          { code: 'ERR_INVALID_ARG_TYPE' }
131        )
132      )
133    );
134  } finally {
135    await fileHandle.close();
136  }
137}
138
139async function doWriteIterableWithEncoding() {
140  const fileHandle = await open(dest, 'w+');
141  try {
142    await fileHandle.writeFile(stream2, 'latin1');
143    const expected = 'ümlaut sechzig';
144    const data = fs.readFileSync(dest, 'latin1');
145    assert.deepStrictEqual(data, expected);
146  } finally {
147    await fileHandle.close();
148  }
149}
150
151async function doWriteBufferIterable() {
152  const fileHandle = await open(dest, 'w+');
153  try {
154    await fileHandle.writeFile(bufferIterable);
155    const data = fs.readFileSync(dest, 'utf-8');
156    assert.deepStrictEqual(data, bufferIterable.expected);
157  } finally {
158    await fileHandle.close();
159  }
160}
161
162async function doWriteAsyncIterable() {
163  const fileHandle = await open(dest, 'w+');
164  try {
165    await fileHandle.writeFile(asyncIterable);
166    const data = fs.readFileSync(dest, 'utf-8');
167    assert.deepStrictEqual(data, asyncIterable.expected);
168  } finally {
169    await fileHandle.close();
170  }
171}
172
173async function doWriteInvalidValues() {
174  const fileHandle = await open(dest, 'w+');
175  try {
176    await Promise.all(
177      [42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) =>
178        assert.rejects(
179          fileHandle.writeFile(value),
180          { code: 'ERR_INVALID_ARG_TYPE' }
181        )
182      )
183    );
184  } finally {
185    await fileHandle.close();
186  }
187}
188
189(async () => {
190  await validateWriteFile();
191  await doWriteAndCancel();
192  await doWriteStream();
193  await doWriteStreamWithCancel();
194  await doWriteIterable();
195  await doWriteInvalidIterable();
196  await doWriteIterableWithEncoding();
197  await doWriteBufferIterable();
198  await doWriteAsyncIterable();
199  await doWriteInvalidValues();
200})().then(common.mustCall());
201