11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci// This test ensures that fs.write accepts "named parameters" object 61cb0ef41Sopenharmony_ci// and doesn't interpret objects as strings 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst assert = require('assert'); 91cb0ef41Sopenharmony_ciconst fs = require('fs'); 101cb0ef41Sopenharmony_ciconst path = require('path'); 111cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 121cb0ef41Sopenharmony_ciconst util = require('util'); 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_citmpdir.refresh(); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciconst destInvalid = path.resolve(tmpdir.path, 'rwopt_invalid'); 171cb0ef41Sopenharmony_ciconst buffer = Buffer.from('zyx'); 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cifunction testInvalidCb(fd, expectedCode, buffer, options, callback) { 201cb0ef41Sopenharmony_ci assert.throws( 211cb0ef41Sopenharmony_ci () => fs.write(fd, buffer, common.mustNotMutateObjectDeep(options), common.mustNotCall()), 221cb0ef41Sopenharmony_ci { code: expectedCode } 231cb0ef41Sopenharmony_ci ); 241cb0ef41Sopenharmony_ci callback(0); 251cb0ef41Sopenharmony_ci} 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cifunction testValidCb(buffer, options, index, callback) { 281cb0ef41Sopenharmony_ci options = common.mustNotMutateObjectDeep(options); 291cb0ef41Sopenharmony_ci const length = options?.length; 301cb0ef41Sopenharmony_ci const offset = options?.offset; 311cb0ef41Sopenharmony_ci const dest = path.resolve(tmpdir.path, `rwopt_valid_${index}`); 321cb0ef41Sopenharmony_ci fs.open(dest, 'w', common.mustSucceed((fd) => { 331cb0ef41Sopenharmony_ci fs.write(fd, buffer, options, common.mustSucceed((bytesWritten, bufferWritten) => { 341cb0ef41Sopenharmony_ci const writeBufCopy = Uint8Array.prototype.slice.call(bufferWritten); 351cb0ef41Sopenharmony_ci fs.close(fd, common.mustSucceed(() => { 361cb0ef41Sopenharmony_ci fs.open(dest, 'r', common.mustSucceed((fd) => { 371cb0ef41Sopenharmony_ci fs.read(fd, buffer, options, common.mustSucceed((bytesRead, bufferRead) => { 381cb0ef41Sopenharmony_ci const readBufCopy = Uint8Array.prototype.slice.call(bufferRead); 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci assert.ok(bytesWritten >= bytesRead); 411cb0ef41Sopenharmony_ci if (length !== undefined && length !== null) { 421cb0ef41Sopenharmony_ci assert.strictEqual(bytesWritten, length); 431cb0ef41Sopenharmony_ci assert.strictEqual(bytesRead, length); 441cb0ef41Sopenharmony_ci } 451cb0ef41Sopenharmony_ci if (offset === undefined || offset === 0) { 461cb0ef41Sopenharmony_ci assert.deepStrictEqual(writeBufCopy, readBufCopy); 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci assert.deepStrictEqual(bufferWritten, bufferRead); 491cb0ef41Sopenharmony_ci fs.close(fd, common.mustSucceed(callback)); 501cb0ef41Sopenharmony_ci })); 511cb0ef41Sopenharmony_ci })); 521cb0ef41Sopenharmony_ci })); 531cb0ef41Sopenharmony_ci })); 541cb0ef41Sopenharmony_ci })); 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci// Promisify to reduce flakiness 581cb0ef41Sopenharmony_ciconst testInvalid = util.promisify(testInvalidCb); 591cb0ef41Sopenharmony_ciconst testValid = util.promisify(testValidCb); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ciasync function runTests(fd) { 621cb0ef41Sopenharmony_ci // Test if first argument is not wrongly interpreted as ArrayBufferView|string 631cb0ef41Sopenharmony_ci for (const badBuffer of [ 641cb0ef41Sopenharmony_ci undefined, null, true, 42, 42n, Symbol('42'), NaN, [], () => {}, 651cb0ef41Sopenharmony_ci Promise.resolve(new Uint8Array(1)), 661cb0ef41Sopenharmony_ci common.mustNotCall(), 671cb0ef41Sopenharmony_ci common.mustNotMutateObjectDeep({}), 681cb0ef41Sopenharmony_ci {}, 691cb0ef41Sopenharmony_ci { buffer: 'amNotParam' }, 701cb0ef41Sopenharmony_ci { string: 'amNotParam' }, 711cb0ef41Sopenharmony_ci { buffer: new Uint8Array(1).buffer }, 721cb0ef41Sopenharmony_ci new Date(), 731cb0ef41Sopenharmony_ci new String('notPrimitive'), 741cb0ef41Sopenharmony_ci { [Symbol.toPrimitive]: (hint) => 'amObject' }, 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci // TODO(LiviaMedeiros): add the following after DEP0162 EOL 771cb0ef41Sopenharmony_ci // { toString() { return 'amObject'; } }, 781cb0ef41Sopenharmony_ci ]) { 791cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', badBuffer, {}); 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci // First argument (buffer or string) is mandatory 831cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', undefined, undefined); 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci // Various invalid options 861cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { length: 5 }); 871cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { offset: 5 }); 881cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { length: 1, offset: 3 }); 891cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { length: -1 }); 901cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { offset: -1 }); 911cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, { offset: false }); 921cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, { offset: true }); 931cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, true); 941cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, '42'); 951cb0ef41Sopenharmony_ci await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, Symbol('42')); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci // Test compatibility with fs.read counterpart 981cb0ef41Sopenharmony_ci for (const [ index, options ] of [ 991cb0ef41Sopenharmony_ci null, 1001cb0ef41Sopenharmony_ci {}, 1011cb0ef41Sopenharmony_ci { length: 1 }, 1021cb0ef41Sopenharmony_ci { position: 5 }, 1031cb0ef41Sopenharmony_ci { length: 1, position: 5 }, 1041cb0ef41Sopenharmony_ci { length: 1, position: -1, offset: 2 }, 1051cb0ef41Sopenharmony_ci { length: null }, 1061cb0ef41Sopenharmony_ci { position: null }, 1071cb0ef41Sopenharmony_ci { offset: 1 }, 1081cb0ef41Sopenharmony_ci ].entries()) { 1091cb0ef41Sopenharmony_ci await testValid(buffer, options, index); 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci} 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_cifs.open(destInvalid, 'w+', common.mustSucceed(async (fd) => { 1141cb0ef41Sopenharmony_ci runTests(fd).then(common.mustCall(() => fs.close(fd, common.mustSucceed()))); 1151cb0ef41Sopenharmony_ci})); 116