11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci// This test ensures that filehandle.write accepts "named parameters" object 61cb0ef41Sopenharmony_ci// and doesn't interpret objects as strings 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst assert = require('assert'); 91cb0ef41Sopenharmony_ciconst fsPromises = require('fs').promises; 101cb0ef41Sopenharmony_ciconst path = require('path'); 111cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_citmpdir.refresh(); 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciconst dest = path.resolve(tmpdir.path, 'tmp.txt'); 161cb0ef41Sopenharmony_ciconst buffer = Buffer.from('zyx'); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciasync function testInvalid(dest, expectedCode, ...params) { 191cb0ef41Sopenharmony_ci if (params.length >= 2) { 201cb0ef41Sopenharmony_ci params[1] = common.mustNotMutateObjectDeep(params[1]); 211cb0ef41Sopenharmony_ci } 221cb0ef41Sopenharmony_ci let fh; 231cb0ef41Sopenharmony_ci try { 241cb0ef41Sopenharmony_ci fh = await fsPromises.open(dest, 'w+'); 251cb0ef41Sopenharmony_ci await assert.rejects( 261cb0ef41Sopenharmony_ci fh.write(...params), 271cb0ef41Sopenharmony_ci { code: expectedCode }); 281cb0ef41Sopenharmony_ci } finally { 291cb0ef41Sopenharmony_ci await fh?.close(); 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci} 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciasync function testValid(dest, buffer, options) { 341cb0ef41Sopenharmony_ci const length = options?.length; 351cb0ef41Sopenharmony_ci const offset = options?.offset; 361cb0ef41Sopenharmony_ci let fh, writeResult, writeBufCopy, readResult, readBufCopy; 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci try { 391cb0ef41Sopenharmony_ci fh = await fsPromises.open(dest, 'w'); 401cb0ef41Sopenharmony_ci writeResult = await fh.write(buffer, options); 411cb0ef41Sopenharmony_ci writeBufCopy = Uint8Array.prototype.slice.call(writeResult.buffer); 421cb0ef41Sopenharmony_ci } finally { 431cb0ef41Sopenharmony_ci await fh?.close(); 441cb0ef41Sopenharmony_ci } 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci try { 471cb0ef41Sopenharmony_ci fh = await fsPromises.open(dest, 'r'); 481cb0ef41Sopenharmony_ci readResult = await fh.read(buffer, options); 491cb0ef41Sopenharmony_ci readBufCopy = Uint8Array.prototype.slice.call(readResult.buffer); 501cb0ef41Sopenharmony_ci } finally { 511cb0ef41Sopenharmony_ci await fh?.close(); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci assert.ok(writeResult.bytesWritten >= readResult.bytesRead); 551cb0ef41Sopenharmony_ci if (length !== undefined && length !== null) { 561cb0ef41Sopenharmony_ci assert.strictEqual(writeResult.bytesWritten, length); 571cb0ef41Sopenharmony_ci assert.strictEqual(readResult.bytesRead, length); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci if (offset === undefined || offset === 0) { 601cb0ef41Sopenharmony_ci assert.deepStrictEqual(writeBufCopy, readBufCopy); 611cb0ef41Sopenharmony_ci } 621cb0ef41Sopenharmony_ci assert.deepStrictEqual(writeResult.buffer, readResult.buffer); 631cb0ef41Sopenharmony_ci} 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci(async () => { 661cb0ef41Sopenharmony_ci // Test if first argument is not wrongly interpreted as ArrayBufferView|string 671cb0ef41Sopenharmony_ci for (const badBuffer of [ 681cb0ef41Sopenharmony_ci undefined, null, true, 42, 42n, Symbol('42'), NaN, [], () => {}, 691cb0ef41Sopenharmony_ci common.mustNotCall(), 701cb0ef41Sopenharmony_ci common.mustNotMutateObjectDeep({}), 711cb0ef41Sopenharmony_ci Promise.resolve(new Uint8Array(1)), 721cb0ef41Sopenharmony_ci {}, 731cb0ef41Sopenharmony_ci { buffer: 'amNotParam' }, 741cb0ef41Sopenharmony_ci { string: 'amNotParam' }, 751cb0ef41Sopenharmony_ci { buffer: new Uint8Array(1).buffer }, 761cb0ef41Sopenharmony_ci new Date(), 771cb0ef41Sopenharmony_ci new String('notPrimitive'), 781cb0ef41Sopenharmony_ci { toString() { return 'amObject'; } }, 791cb0ef41Sopenharmony_ci { [Symbol.toPrimitive]: (hint) => 'amObject' }, 801cb0ef41Sopenharmony_ci ]) { 811cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_INVALID_ARG_TYPE', common.mustNotMutateObjectDeep(badBuffer), {}); 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci // First argument (buffer or string) is mandatory 851cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_INVALID_ARG_TYPE'); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci // Various invalid options 881cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { length: 5 }); 891cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { offset: 5 }); 901cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { length: 1, offset: 3 }); 911cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { length: -1 }); 921cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { offset: -1 }); 931cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_INVALID_ARG_TYPE', buffer, { offset: false }); 941cb0ef41Sopenharmony_ci await testInvalid(dest, 'ERR_INVALID_ARG_TYPE', buffer, { offset: true }); 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci // Test compatibility with filehandle.read counterpart 971cb0ef41Sopenharmony_ci for (const options of [ 981cb0ef41Sopenharmony_ci undefined, 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 ]) { 1091cb0ef41Sopenharmony_ci await testValid(dest, buffer, common.mustNotMutateObjectDeep(options)); 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci})().then(common.mustCall()); 112