11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci// This test ensures that fs.writeSync 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_ci
131cb0ef41Sopenharmony_citmpdir.refresh();
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciconst dest = path.resolve(tmpdir.path, 'tmp.txt');
161cb0ef41Sopenharmony_ciconst buffer = Buffer.from('zyx');
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cifunction testInvalid(dest, expectedCode, ...bufferAndOptions) {
191cb0ef41Sopenharmony_ci  if (bufferAndOptions.length >= 2) {
201cb0ef41Sopenharmony_ci    bufferAndOptions[1] = common.mustNotMutateObjectDeep(bufferAndOptions[1]);
211cb0ef41Sopenharmony_ci  }
221cb0ef41Sopenharmony_ci  let fd;
231cb0ef41Sopenharmony_ci  try {
241cb0ef41Sopenharmony_ci    fd = fs.openSync(dest, 'w+');
251cb0ef41Sopenharmony_ci    assert.throws(
261cb0ef41Sopenharmony_ci      () => fs.writeSync(fd, ...bufferAndOptions),
271cb0ef41Sopenharmony_ci      { code: expectedCode });
281cb0ef41Sopenharmony_ci  } finally {
291cb0ef41Sopenharmony_ci    if (fd != null) fs.closeSync(fd);
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci}
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cifunction testValid(dest, buffer, options) {
341cb0ef41Sopenharmony_ci  const length = options?.length;
351cb0ef41Sopenharmony_ci  let fd, bytesWritten, bytesRead;
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  try {
381cb0ef41Sopenharmony_ci    fd = fs.openSync(dest, 'w');
391cb0ef41Sopenharmony_ci    bytesWritten = fs.writeSync(fd, buffer, options);
401cb0ef41Sopenharmony_ci  } finally {
411cb0ef41Sopenharmony_ci    if (fd != null) fs.closeSync(fd);
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  try {
451cb0ef41Sopenharmony_ci    fd = fs.openSync(dest, 'r');
461cb0ef41Sopenharmony_ci    bytesRead = fs.readSync(fd, buffer, options);
471cb0ef41Sopenharmony_ci  } finally {
481cb0ef41Sopenharmony_ci    if (fd != null) fs.closeSync(fd);
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  assert.ok(bytesWritten >= bytesRead);
521cb0ef41Sopenharmony_ci  if (length !== undefined && length !== null) {
531cb0ef41Sopenharmony_ci    assert.strictEqual(bytesWritten, length);
541cb0ef41Sopenharmony_ci    assert.strictEqual(bytesRead, length);
551cb0ef41Sopenharmony_ci  }
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci{
591cb0ef41Sopenharmony_ci  // Test if second argument is not wrongly interpreted as string or options
601cb0ef41Sopenharmony_ci  for (const badBuffer of [
611cb0ef41Sopenharmony_ci    undefined, null, true, 42, 42n, Symbol('42'), NaN, [], () => {},
621cb0ef41Sopenharmony_ci    common.mustNotCall(),
631cb0ef41Sopenharmony_ci    common.mustNotMutateObjectDeep({}),
641cb0ef41Sopenharmony_ci    {},
651cb0ef41Sopenharmony_ci    { buffer: 'amNotParam' },
661cb0ef41Sopenharmony_ci    { string: 'amNotParam' },
671cb0ef41Sopenharmony_ci    { buffer: new Uint8Array(1) },
681cb0ef41Sopenharmony_ci    { buffer: new Uint8Array(1).buffer },
691cb0ef41Sopenharmony_ci    Promise.resolve(new Uint8Array(1)),
701cb0ef41Sopenharmony_ci    new Date(),
711cb0ef41Sopenharmony_ci    new String('notPrimitive'),
721cb0ef41Sopenharmony_ci    { toString() { return 'amObject'; } },
731cb0ef41Sopenharmony_ci    { [Symbol.toPrimitive]: (hint) => 'amObject' },
741cb0ef41Sopenharmony_ci  ]) {
751cb0ef41Sopenharmony_ci    testInvalid(dest, 'ERR_INVALID_ARG_TYPE', common.mustNotMutateObjectDeep(badBuffer));
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  // First argument (buffer or string) is mandatory
791cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_INVALID_ARG_TYPE');
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  // Various invalid options
821cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { length: 5 });
831cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { offset: 5 });
841cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { length: 1, offset: 3 });
851cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { length: -1 });
861cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_OUT_OF_RANGE', buffer, { offset: -1 });
871cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_INVALID_ARG_TYPE', buffer, { offset: false });
881cb0ef41Sopenharmony_ci  testInvalid(dest, 'ERR_INVALID_ARG_TYPE', buffer, { offset: true });
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  // Test compatibility with fs.readSync counterpart with reused options
911cb0ef41Sopenharmony_ci  for (const options of [
921cb0ef41Sopenharmony_ci    undefined,
931cb0ef41Sopenharmony_ci    null,
941cb0ef41Sopenharmony_ci    {},
951cb0ef41Sopenharmony_ci    { length: 1 },
961cb0ef41Sopenharmony_ci    { position: 5 },
971cb0ef41Sopenharmony_ci    { length: 1, position: 5 },
981cb0ef41Sopenharmony_ci    { length: 1, position: -1, offset: 2 },
991cb0ef41Sopenharmony_ci    { length: null },
1001cb0ef41Sopenharmony_ci    { position: null },
1011cb0ef41Sopenharmony_ci    { offset: 1 },
1021cb0ef41Sopenharmony_ci  ]) {
1031cb0ef41Sopenharmony_ci    testValid(dest, buffer, common.mustNotMutateObjectDeep(options));
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci}
106