Skip to content

Commit ad71818

Browse files
committed
squash: add test for fs.write()
1 parent b0d9356 commit ad71818

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
// This test ensures that fs.write accepts "named parameters" object
6+
// and doesn't interpret objects as strings
7+
8+
const assert = require('assert');
9+
const fs = require('fs');
10+
const path = require('path');
11+
const tmpdir = require('../common/tmpdir');
12+
13+
tmpdir.refresh();
14+
15+
const destInvalid = path.resolve(tmpdir.path, 'rwopt_invalid');
16+
const buffer = Buffer.from('zyx');
17+
18+
function testInvalid(fd, expectedCode, ...params) {
19+
assert.throws(
20+
() => fs.write(fd, ...params, common.mustNotCall()),
21+
{ code: expectedCode }
22+
);
23+
}
24+
25+
function testValid([ buffer, options ], index) {
26+
const dest = path.resolve(tmpdir.path, `rwopt_valid_${index}`);
27+
fs.open(dest, 'w+', common.mustSucceed((fd) => {
28+
fs.write(fd, buffer, options, common.mustSucceed((bytesWritten, bufferWritten) => {
29+
const writeBufCopy = Uint8Array.prototype.slice.call(bufferWritten);
30+
31+
// TODO: replace this with fs.read(fd, buffer, options, cb) if it is supported
32+
fs.read(fd, { buffer, ...options }, common.mustSucceed((bytesRead, bufferRead) => {
33+
const readBufCopy = Uint8Array.prototype.slice.call(bufferRead);
34+
35+
assert.ok(bytesWritten >= bytesRead);
36+
if (options.length !== undefined && options.length !== null) {
37+
assert.strictEqual(bytesWritten, options.length);
38+
}
39+
if (options.offset === undefined || options.offset === 0) {
40+
assert.deepStrictEqual(writeBufCopy, readBufCopy);
41+
}
42+
assert.deepStrictEqual(bufferWritten, bufferRead);
43+
fs.close(fd, common.mustSucceed());
44+
}));
45+
}));
46+
}));
47+
}
48+
49+
fs.open(destInvalid, 'w+', common.mustSucceed((fd) => {
50+
// Test if first argument is not wrongly interpreted as ArrayBufferView|string
51+
for (const badBuffer of [
52+
undefined, null, true, 42, 42n, Symbol('42'), NaN, [], () => {},
53+
Promise.resolve(new Uint8Array(1)),
54+
{},
55+
{ buffer: 'amNotParam' },
56+
{ string: 'amNotParam' },
57+
{ buffer: new Uint8Array(1).buffer },
58+
new Date(),
59+
new String('notPrimitive'),
60+
{ [Symbol.toPrimitive]: (hint) => 'amObject' },
61+
62+
// TODO: add the following after DEP0162 EOL
63+
// { toString() { return 'amObject'; } },
64+
]) {
65+
testInvalid(fd, 'ERR_INVALID_ARG_TYPE', badBuffer, {});
66+
}
67+
68+
// First argument (buffer or string) is mandatory
69+
testInvalid(fd, 'ERR_INVALID_ARG_TYPE');
70+
71+
// Various invalid options
72+
testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { length: 5 });
73+
testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { offset: 5 });
74+
testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { length: 1, offset: 3 });
75+
testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { length: -1 });
76+
testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { offset: -1 });
77+
testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, { offset: false });
78+
testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, { offset: true });
79+
80+
// Test compatibility with fs.read counterpart
81+
[
82+
[ buffer, {} ],
83+
[ buffer, { length: 1 } ],
84+
[ buffer, { position: 5 } ],
85+
[ buffer, { length: 1, position: 5 } ],
86+
[ buffer, { length: 1, position: -1, offset: 2 } ],
87+
[ buffer, { length: null } ],
88+
[ buffer, { position: null } ],
89+
[ buffer, { offset: 1 } ],
90+
].forEach(testValid);
91+
}));

0 commit comments

Comments
 (0)