fs: add support for async iterators to `fsPromises.writeFile` · nodejs/node@b6f4901

@@ -7,20 +7,115 @@ const path = require('path');

77

const tmpdir = require('../common/tmpdir');

88

const assert = require('assert');

99

const tmpDir = tmpdir.path;

10+

const { Readable } = require('stream');

10111112

tmpdir.refresh();

12131314

const dest = path.resolve(tmpDir, 'tmp.txt');

1415

const otherDest = path.resolve(tmpDir, 'tmp-2.txt');

1516

const buffer = Buffer.from('abc'.repeat(1000));

1617

const 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+

};

17511852

async function doWrite() {

1953

await fsPromises.writeFile(dest, buffer);

2054

const data = fs.readFileSync(dest);

2155

assert.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+24119

async function doWriteWithCancel() {

25120

const controller = new AbortController();

26121

const { signal } = controller;

@@ -50,9 +145,18 @@ async function doReadWithEncoding() {

50145

assert.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());