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