test: use common.mustNotMutateObjectDeep() in fs tests

PR-URL: https://github.com/nodejs/node/pull/43819
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
Livia Medeiros
2022-07-24 22:29:06 +09:00
committed by GitHub
parent eb4dca030d
commit 050d974a25
19 changed files with 216 additions and 190 deletions

View File

@@ -145,7 +145,7 @@ assert.throws(
assert.throws(
() => {
fs.access(__filename, fs.F_OK, {});
fs.access(__filename, fs.F_OK, common.mustNotMutateObjectDeep({}));
},
{
code: 'ERR_INVALID_ARG_TYPE',

View File

@@ -71,17 +71,17 @@ const fileData3 = fs.readFileSync(filename3);
assert.strictEqual(buf.length + currentFileData.length, fileData3.length);
const filename4 = join(tmpdir.path, 'append-sync4.txt');
fs.writeFileSync(filename4, currentFileData, { mode: m });
fs.writeFileSync(filename4, currentFileData, common.mustNotMutateObjectDeep({ mode: m }));
[
true, false, 0, 1, Infinity, () => {}, {}, [], undefined, null,
].forEach((value) => {
assert.throws(
() => fs.appendFileSync(filename4, value, { mode: m }),
() => fs.appendFileSync(filename4, value, common.mustNotMutateObjectDeep({ mode: m })),
{ message: /data/, code: 'ERR_INVALID_ARG_TYPE' }
);
});
fs.appendFileSync(filename4, `${num}`, { mode: m });
fs.appendFileSync(filename4, `${num}`, common.mustNotMutateObjectDeep({ mode: m }));
// Windows permissions aren't Unix.
if (!common.isWindows) {

View File

@@ -1,4 +1,4 @@
import { mustCall } from '../common/index.mjs';
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
import assert from 'assert';
import fs from 'fs';
@@ -34,19 +34,19 @@ function nextdir() {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
assertDirEquivalent(src, dest);
}
// It does not throw errors when directory is copied over and force is false.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'README.md'), 'hello world', 'utf8');
const dest = nextdir();
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
const initialStat = lstatSync(join(dest, 'README.md'));
cpSync(src, dest, { force: false, recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ force: false, recursive: true }));
// File should not have been copied over, so access times will be identical:
assertDirEquivalent(src, dest);
const finalStat = lstatSync(join(dest, 'README.md'));
@@ -57,9 +57,9 @@ function nextdir() {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(dest, 'README.md'), '# Goodbye', 'utf8');
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
assertDirEquivalent(src, dest);
const content = readFileSync(join(dest, 'README.md'), 'utf8');
assert.strictEqual(content.trim(), '# Hello');
@@ -71,8 +71,8 @@ function nextdir() {
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
const destFile = join(dest, 'a/b/README2.md');
cpSync(src, dest, { dereference: true, recursive: true });
cpSync(src, dest, { dereference: true, recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ dereference: true, recursive: true }));
cpSync(src, dest, mustNotMutateObjectDeep({ dereference: true, recursive: true }));
const stat = lstatSync(destFile);
assert(stat.isFile());
}
@@ -81,15 +81,15 @@ function nextdir() {
// It copies file itself, rather than symlink, when dereference is true.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'foo.js'), 'foo', 'utf8');
symlinkSync(join(src, 'foo.js'), join(src, 'bar.js'));
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
const destFile = join(dest, 'foo.js');
cpSync(join(src, 'bar.js'), destFile, { dereference: true, recursive: true });
cpSync(join(src, 'bar.js'), destFile, mustNotMutateObjectDeep({ dereference: true, recursive: true }));
const stat = lstatSync(destFile);
assert(stat.isFile());
}
@@ -112,7 +112,7 @@ function nextdir() {
{
const src = './test/fixtures/copy/kitchen-sink';
assert.throws(
() => cpSync(src, src, { dereference: true, verbatimSymlinks: true }),
() => cpSync(src, src, mustNotMutateObjectDeep({ dereference: true, verbatimSymlinks: true })),
{ code: 'ERR_INCOMPATIBLE_OPTION_PAIR' }
);
}
@@ -121,14 +121,14 @@ function nextdir() {
// It resolves relative symlinks to their absolute path by default.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'foo.js'), 'foo', 'utf8');
symlinkSync('foo.js', join(src, 'bar.js'));
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
const link = readlinkSync(join(dest, 'bar.js'));
assert.strictEqual(link, join(src, 'foo.js'));
}
@@ -137,14 +137,14 @@ function nextdir() {
// It resolves relative symlinks when verbatimSymlinks is false.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'foo.js'), 'foo', 'utf8');
symlinkSync('foo.js', join(src, 'bar.js'));
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
cpSync(src, dest, { recursive: true, verbatimSymlinks: false });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true, verbatimSymlinks: false }));
const link = readlinkSync(join(dest, 'bar.js'));
assert.strictEqual(link, join(src, 'foo.js'));
}
@@ -153,14 +153,14 @@ function nextdir() {
// It does not resolve relative symlinks when verbatimSymlinks is true.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'foo.js'), 'foo', 'utf8');
symlinkSync('foo.js', join(src, 'bar.js'));
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
cpSync(src, dest, { recursive: true, verbatimSymlinks: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true, verbatimSymlinks: true }));
const link = readlinkSync(join(dest, 'bar.js'));
assert.strictEqual(link, 'foo.js');
}
@@ -178,13 +178,13 @@ function nextdir() {
// It throws error if symlink in src points to location in dest.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
const dest = nextdir();
mkdirSync(dest);
symlinkSync(dest, join(src, 'link'));
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
assert.throws(
() => cpSync(src, dest, { recursive: true }),
() => cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true })),
{
code: 'ERR_FS_CP_EINVAL'
}
@@ -194,14 +194,14 @@ function nextdir() {
// It throws error if symlink in dest points to location in src.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c'));
const dest = nextdir();
mkdirSync(join(dest, 'a'), { recursive: true });
mkdirSync(join(dest, 'a'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(src, join(dest, 'a', 'c'));
assert.throws(
() => cpSync(src, dest, { recursive: true }),
() => cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true })),
{ code: 'ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY' }
);
}
@@ -209,11 +209,11 @@ function nextdir() {
// It throws error if parent directory of symlink in dest points to src.
{
const src = nextdir();
mkdirSync(join(src, 'a'), { recursive: true });
mkdirSync(join(src, 'a'), mustNotMutateObjectDeep({ recursive: true }));
const dest = nextdir();
// Create symlink in dest pointing to src.
const destLink = join(dest, 'b');
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(src, destLink);
assert.throws(
() => cpSync(src, join(dest, 'b', 'c')),
@@ -224,7 +224,7 @@ function nextdir() {
// It throws error if attempt is made to copy directory to file.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
const dest = './test/fixtures/copy/kitchen-sink/README.md';
assert.throws(
() => cpSync(src, dest),
@@ -236,7 +236,7 @@ function nextdir() {
{
const srcFile = './test/fixtures/copy/kitchen-sink/index.js';
const destFile = join(nextdir(), 'index.js');
cpSync(srcFile, destFile, { dereference: true });
cpSync(srcFile, destFile, mustNotMutateObjectDeep({ dereference: true }));
const stat = lstatSync(destFile);
assert(stat.isFile());
}
@@ -256,7 +256,7 @@ function nextdir() {
{
const src = './test/fixtures/copy/kitchen-sink/README.md';
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
assert.throws(
() => cpSync(src, dest),
{ code: 'ERR_FS_CP_NON_DIR_TO_DIR' }
@@ -290,7 +290,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
cpSync(src, dest, { preserveTimestamps: true, recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ preserveTimestamps: true, recursive: true }));
assertDirEquivalent(src, dest);
const srcStat = lstatSync(join(src, 'index.js'));
const destStat = lstatSync(join(dest, 'index.js'));
@@ -341,7 +341,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
assert.throws(
() => cpSync(src, dest, {
dereference: true,
@@ -356,14 +356,14 @@ if (!isWindows) {
// It throws EEXIST error if attempt is made to copy symlink over file.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c'));
const dest = nextdir();
mkdirSync(join(dest, 'a'), { recursive: true });
mkdirSync(join(dest, 'a'), mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(dest, 'a', 'c'), 'hello', 'utf8');
assert.throws(
() => cpSync(src, dest, { recursive: true }),
() => cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true })),
{ code: 'EEXIST' }
);
}
@@ -371,11 +371,11 @@ if (!isWindows) {
// It makes file writeable when updating timestamp, if not writeable.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
const dest = nextdir();
mkdirSync(dest, { recursive: true });
writeFileSync(join(src, 'foo.txt'), 'foo', { mode: 0o444 });
cpSync(src, dest, { preserveTimestamps: true, recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'foo.txt'), 'foo', mustNotMutateObjectDeep({ mode: 0o444 }));
cpSync(src, dest, mustNotMutateObjectDeep({ preserveTimestamps: true, recursive: true }));
assertDirEquivalent(src, dest);
const srcStat = lstatSync(join(src, 'foo.txt'));
const destStat = lstatSync(join(dest, 'foo.txt'));
@@ -385,12 +385,12 @@ if (!isWindows) {
// It copies link if it does not point to folder in src.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(src, join(src, 'a', 'c'));
const dest = nextdir();
mkdirSync(join(dest, 'a'), { recursive: true });
mkdirSync(join(dest, 'a'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(dest, join(dest, 'a', 'c'));
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
const link = readlinkSync(join(dest, 'a', 'c'));
assert.strictEqual(link, src);
}
@@ -399,7 +399,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
cpSync(pathToFileURL(src), pathToFileURL(dest), { recursive: true });
cpSync(pathToFileURL(src), pathToFileURL(dest), mustNotMutateObjectDeep({ recursive: true }));
assertDirEquivalent(src, dest);
}
@@ -417,7 +417,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
cp(src, dest, { recursive: true }, mustCall((err) => {
cp(src, dest, mustNotMutateObjectDeep({ recursive: true }), mustCall((err) => {
assert.strictEqual(err, null);
assertDirEquivalent(src, dest);
}));
@@ -426,10 +426,10 @@ if (!isWindows) {
// It does not throw errors when directory is copied over and force is false.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'README.md'), 'hello world', 'utf8');
const dest = nextdir();
cpSync(src, dest, { dereference: true, recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ dereference: true, recursive: true }));
const initialStat = lstatSync(join(dest, 'README.md'));
cp(src, dest, {
dereference: true,
@@ -448,10 +448,10 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(dest, 'README.md'), '# Goodbye', 'utf8');
cp(src, dest, { recursive: true }, mustCall((err) => {
cp(src, dest, mustNotMutateObjectDeep({ recursive: true }), mustCall((err) => {
assert.strictEqual(err, null);
assertDirEquivalent(src, dest);
const content = readFileSync(join(dest, 'README.md'), 'utf8');
@@ -465,7 +465,7 @@ if (!isWindows) {
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
const destFile = join(dest, 'a/b/README2.md');
cpSync(src, dest, { dereference: true, recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ dereference: true, recursive: true }));
cp(src, dest, {
dereference: true,
recursive: true
@@ -479,15 +479,15 @@ if (!isWindows) {
// It copies file itself, rather than symlink, when dereference is true.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'foo.js'), 'foo', 'utf8');
symlinkSync(join(src, 'foo.js'), join(src, 'bar.js'));
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
const destFile = join(dest, 'foo.js');
cp(join(src, 'bar.js'), destFile, { dereference: true },
cp(join(src, 'bar.js'), destFile, mustNotMutateObjectDeep({ dereference: true }),
mustCall((err) => {
assert.strictEqual(err, null);
const stat = lstatSync(destFile);
@@ -507,12 +507,12 @@ if (!isWindows) {
// It returns error if symlink in src points to location in dest.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
const dest = nextdir();
mkdirSync(dest);
symlinkSync(dest, join(src, 'link'));
cpSync(src, dest, { recursive: true });
cp(src, dest, { recursive: true }, mustCall((err) => {
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
cp(src, dest, mustNotMutateObjectDeep({ recursive: true }), mustCall((err) => {
assert.strictEqual(err.code, 'ERR_FS_CP_EINVAL');
}));
}
@@ -520,13 +520,13 @@ if (!isWindows) {
// It returns error if symlink in dest points to location in src.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c'));
const dest = nextdir();
mkdirSync(join(dest, 'a'), { recursive: true });
mkdirSync(join(dest, 'a'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(src, join(dest, 'a', 'c'));
cp(src, dest, { recursive: true }, mustCall((err) => {
cp(src, dest, mustNotMutateObjectDeep({ recursive: true }), mustCall((err) => {
assert.strictEqual(err.code, 'ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY');
}));
}
@@ -534,11 +534,11 @@ if (!isWindows) {
// It returns error if parent directory of symlink in dest points to src.
{
const src = nextdir();
mkdirSync(join(src, 'a'), { recursive: true });
mkdirSync(join(src, 'a'), mustNotMutateObjectDeep({ recursive: true }));
const dest = nextdir();
// Create symlink in dest pointing to src.
const destLink = join(dest, 'b');
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(src, destLink);
cp(src, join(dest, 'b', 'c'), mustCall((err) => {
assert.strictEqual(err.code, 'ERR_FS_CP_EINVAL');
@@ -548,7 +548,7 @@ if (!isWindows) {
// It returns error if attempt is made to copy directory to file.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
const dest = './test/fixtures/copy/kitchen-sink/README.md';
cp(src, dest, mustCall((err) => {
assert.strictEqual(err.code, 'ERR_FS_CP_DIR_TO_NON_DIR');
@@ -559,7 +559,7 @@ if (!isWindows) {
{
const srcFile = './test/fixtures/copy/kitchen-sink/README.md';
const destFile = join(nextdir(), 'index.js');
cp(srcFile, destFile, { dereference: true }, mustCall((err) => {
cp(srcFile, destFile, mustNotMutateObjectDeep({ dereference: true }), mustCall((err) => {
assert.strictEqual(err, null);
const stat = lstatSync(destFile);
assert(stat.isFile());
@@ -579,7 +579,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink/README.md';
const dest = nextdir();
mkdirSync(dest, { recursive: true });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
cp(src, dest, mustCall((err) => {
assert.strictEqual(err.code, 'ERR_FS_CP_NON_DIR_TO_DIR');
}));
@@ -676,7 +676,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
cpSync(src, dest, { recursive: true });
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
cp(src, dest, {
dereference: true,
errorOnExist: true,
@@ -690,13 +690,13 @@ if (!isWindows) {
// It returns EEXIST error if attempt is made to copy symlink over file.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c'));
const dest = nextdir();
mkdirSync(join(dest, 'a'), { recursive: true });
mkdirSync(join(dest, 'a'), mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(dest, 'a', 'c'), 'hello', 'utf8');
cp(src, dest, { recursive: true }, mustCall((err) => {
cp(src, dest, mustNotMutateObjectDeep({ recursive: true }), mustCall((err) => {
assert.strictEqual(err.code, 'EEXIST');
}));
}
@@ -704,10 +704,10 @@ if (!isWindows) {
// It makes file writeable when updating timestamp, if not writeable.
{
const src = nextdir();
mkdirSync(src, { recursive: true });
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
const dest = nextdir();
mkdirSync(dest, { recursive: true });
writeFileSync(join(src, 'foo.txt'), 'foo', { mode: 0o444 });
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
writeFileSync(join(src, 'foo.txt'), 'foo', mustNotMutateObjectDeep({ mode: 0o444 }));
cp(src, dest, {
preserveTimestamps: true,
recursive: true,
@@ -723,12 +723,12 @@ if (!isWindows) {
// It copies link if it does not point to folder in src.
{
const src = nextdir();
mkdirSync(join(src, 'a', 'b'), { recursive: true });
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(src, join(src, 'a', 'c'));
const dest = nextdir();
mkdirSync(join(dest, 'a'), { recursive: true });
mkdirSync(join(dest, 'a'), mustNotMutateObjectDeep({ recursive: true }));
symlinkSync(dest, join(dest, 'a', 'c'));
cp(src, dest, { recursive: true }, mustCall((err) => {
cp(src, dest, mustNotMutateObjectDeep({ recursive: true }), mustCall((err) => {
assert.strictEqual(err, null);
const link = readlinkSync(join(dest, 'a', 'c'));
assert.strictEqual(link, src);
@@ -739,7 +739,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
cp(pathToFileURL(src), pathToFileURL(dest), { recursive: true },
cp(pathToFileURL(src), pathToFileURL(dest), mustNotMutateObjectDeep({ recursive: true }),
mustCall((err) => {
assert.strictEqual(err, null);
assertDirEquivalent(src, dest);
@@ -760,7 +760,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
const p = await fs.promises.cp(src, dest, { recursive: true });
const p = await fs.promises.cp(src, dest, mustNotMutateObjectDeep({ recursive: true }));
assert.strictEqual(p, undefined);
assertDirEquivalent(src, dest);
}
@@ -782,7 +782,7 @@ if (!isWindows) {
{
const src = './test/fixtures/copy/kitchen-sink';
const dest = nextdir();
await fs.promises.cp(src, dest, { recursive: true });
await fs.promises.cp(src, dest, mustNotMutateObjectDeep({ recursive: true }));
await assert.rejects(
fs.promises.cp(src, dest, {
dereference: true,
@@ -824,7 +824,7 @@ function assertDirEquivalent(dir1, dir2) {
}
function collectEntries(dir, dirEntries) {
const newEntries = readdirSync(dir, { withFileTypes: true });
const newEntries = readdirSync(dir, mustNotMutateObjectDeep({ withFileTypes: true }));
for (const entry of newEntries) {
if (entry.isDirectory()) {
collectEntries(join(dir, entry.name), dirEntries);

View File

@@ -57,7 +57,7 @@ function nextdir() {
{
const pathname = path.join(tmpdir.path, nextdir());
fs.mkdir(pathname, { mode: 0o777 }, common.mustCall(function(err) {
fs.mkdir(pathname, common.mustNotMutateObjectDeep({ mode: 0o777 }), common.mustCall(function(err) {
assert.strictEqual(err, null);
assert.strictEqual(fs.existsSync(pathname), true);
}));
@@ -67,7 +67,7 @@ function nextdir() {
{
const pathname = path.join(tmpdir.path, nextdir());
fs.mkdirSync(pathname, { mode: 0o777 });
fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ mode: 0o777 }));
assert.strictEqual(fs.existsSync(pathname), true);
}
@@ -105,7 +105,7 @@ function nextdir() {
{
const pathname = path.join(tmpdir.path, nextdir(), nextdir());
fs.mkdirSync(pathname, { recursive: true });
fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true }));
const exists = fs.existsSync(pathname);
assert.strictEqual(exists, true);
@@ -142,7 +142,7 @@ function nextdir() {
fs.writeFileSync(pathname, '', 'utf8');
assert.throws(
() => { fs.mkdirSync(pathname, { recursive: true }); },
() => { fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); },
{
code: 'EEXIST',
message: /EEXIST: .*mkdir/,
@@ -176,7 +176,7 @@ function nextdir() {
{
const pathname = path.join(tmpdir.path, nextdir(), nextdir());
fs.mkdir(pathname, { recursive: true }, common.mustCall(function(err) {
fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err) {
assert.strictEqual(err, null);
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
@@ -189,7 +189,7 @@ function nextdir() {
fs.mkdirSync(path.dirname(pathname));
fs.writeFileSync(pathname, '', 'utf8');
fs.mkdir(pathname, { recursive: true }, common.mustCall((err) => {
fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall((err) => {
assert.strictEqual(err.code, 'EEXIST');
assert.strictEqual(err.syscall, 'mkdir');
assert.strictEqual(fs.statSync(pathname).isDirectory(), false);
@@ -203,7 +203,7 @@ function nextdir() {
fs.mkdirSync(path.dirname(filename));
fs.writeFileSync(filename, '', 'utf8');
fs.mkdir(pathname, { recursive: true }, common.mustCall((err) => {
fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall((err) => {
assert.strictEqual(err.code, 'ENOTDIR');
assert.strictEqual(err.syscall, 'mkdir');
assert.strictEqual(fs.existsSync(pathname), false);
@@ -223,7 +223,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
process.chdir(pathname);
fs.rmdirSync(pathname);
assert.throws(
() => { fs.mkdirSync('X', { recursive: true }); },
() => { fs.mkdirSync('X', common.mustNotMutateObjectDeep({ recursive: true })); },
{
code: 'ENOENT',
message: /ENOENT: .*mkdir/,
@@ -231,7 +231,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
syscall: 'mkdir',
}
);
fs.mkdir('X', { recursive: true }, (err) => {
fs.mkdir('X', common.mustNotMutateObjectDeep({ recursive: true }), (err) => {
assert.strictEqual(err.code, 'ENOENT');
assert.strictEqual(err.syscall, 'mkdir');
});
@@ -244,7 +244,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
['', 1, {}, [], null, Symbol('test'), () => {}].forEach((recursive) => {
const received = common.invalidArgTypeHelper(recursive);
assert.throws(
() => fs.mkdir(pathname, { recursive }, common.mustNotCall()),
() => fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive }), common.mustNotCall()),
{
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
@@ -253,7 +253,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
}
);
assert.throws(
() => fs.mkdirSync(pathname, { recursive }),
() => fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive })),
{
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
@@ -271,7 +271,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
const firstPathCreated = path.join(tmpdir.path, dir1);
const pathname = path.join(tmpdir.path, dir1, dir2);
fs.mkdir(pathname, { recursive: true }, common.mustCall(function(err, path) {
fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) {
assert.strictEqual(err, null);
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
@@ -285,7 +285,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
const dir2 = nextdir();
const pathname = path.join(tmpdir.path, dir1, dir2);
fs.mkdirSync(path.join(tmpdir.path, dir1));
fs.mkdir(pathname, { recursive: true }, common.mustCall(function(err, path) {
fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) {
assert.strictEqual(err, null);
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
@@ -298,8 +298,8 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
const dir1 = nextdir();
const dir2 = nextdir();
const pathname = path.join(tmpdir.path, dir1, dir2);
fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), { recursive: true });
fs.mkdir(pathname, { recursive: true }, common.mustCall(function(err, path) {
fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), common.mustNotMutateObjectDeep({ recursive: true }));
fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) {
assert.strictEqual(err, null);
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
@@ -313,7 +313,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
const dir2 = nextdir();
const firstPathCreated = path.join(tmpdir.path, dir1);
const pathname = path.join(tmpdir.path, dir1, dir2);
const p = fs.mkdirSync(pathname, { recursive: true });
const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true }));
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
assert.strictEqual(p, firstPathCreated);
@@ -324,8 +324,8 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
const dir1 = nextdir();
const dir2 = nextdir();
const pathname = path.join(tmpdir.path, dir1, dir2);
fs.mkdirSync(path.join(tmpdir.path, dir1), { recursive: true });
const p = fs.mkdirSync(pathname, { recursive: true });
fs.mkdirSync(path.join(tmpdir.path, dir1), common.mustNotMutateObjectDeep({ recursive: true }));
const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true }));
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
assert.strictEqual(p, pathname);
@@ -336,8 +336,8 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
const dir1 = nextdir();
const dir2 = nextdir();
const pathname = path.join(tmpdir.path, dir1, dir2);
fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), { recursive: true });
const p = fs.mkdirSync(pathname, { recursive: true });
fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), common.mustNotMutateObjectDeep({ recursive: true }));
const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true }));
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
assert.strictEqual(p, undefined);
@@ -350,7 +350,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) {
const firstPathCreated = path.join(tmpdir.path, dir1);
const pathname = path.join(tmpdir.path, dir1, dir2);
async function testCase() {
const p = await fs.promises.mkdir(pathname, { recursive: true });
const p = await fs.promises.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }));
assert.strictEqual(fs.existsSync(pathname), true);
assert.strictEqual(fs.statSync(pathname).isDirectory(), true);
assert.strictEqual(p, firstPathCreated);

View File

@@ -194,14 +194,14 @@ doAsyncIterThrowTest().then(common.mustCall());
// Check error thrown on invalid values of bufferSize
for (const bufferSize of [-1, 0, 0.5, 1.5, Infinity, NaN]) {
assert.throws(
() => fs.opendirSync(testDir, { bufferSize }),
() => fs.opendirSync(testDir, common.mustNotMutateObjectDeep({ bufferSize })),
{
code: 'ERR_OUT_OF_RANGE'
});
}
for (const bufferSize of ['', '1', null]) {
assert.throws(
() => fs.opendirSync(testDir, { bufferSize }),
() => fs.opendirSync(testDir, common.mustNotMutateObjectDeep({ bufferSize })),
{
code: 'ERR_INVALID_ARG_TYPE'
});
@@ -209,7 +209,7 @@ for (const bufferSize of ['', '1', null]) {
// Check that passing a positive integer as bufferSize works
{
const dir = fs.opendirSync(testDir, { bufferSize: 1024 });
const dir = fs.opendirSync(testDir, common.mustNotMutateObjectDeep({ bufferSize: 1024 }));
assertDirent(dir.readSync());
dir.close();
}

View File

@@ -60,7 +60,7 @@ async function doReadAndCancel() {
const buffer = Buffer.from('Dogs running'.repeat(10000), 'utf8');
fs.writeFileSync(filePathForHandle, buffer);
const signal = AbortSignal.abort();
await assert.rejects(readFile(fileHandle, { signal }), {
await assert.rejects(readFile(fileHandle, common.mustNotMutateObjectDeep({ signal })), {
name: 'AbortError'
});
} finally {
@@ -77,7 +77,7 @@ async function doReadAndCancel() {
const controller = new AbortController();
const { signal } = controller;
process.nextTick(() => controller.abort());
await assert.rejects(readFile(fileHandle, { signal }), {
await assert.rejects(readFile(fileHandle, common.mustNotMutateObjectDeep({ signal })), {
name: 'AbortError'
}, 'tick-0');
await fileHandle.close();
@@ -94,7 +94,7 @@ async function doReadAndCancel() {
const controller = new AbortController();
const { signal } = controller;
tick(1, () => controller.abort());
await assert.rejects(fileHandle.readFile({ signal, encoding: 'utf8' }), {
await assert.rejects(fileHandle.readFile(common.mustNotMutateObjectDeep({ signal, encoding: 'utf8' })), {
name: 'AbortError'
}, 'tick-1');

View File

@@ -16,6 +16,9 @@ const dest = path.resolve(tmpdir.path, 'tmp.txt');
const buffer = Buffer.from('zyx');
async function testInvalid(dest, expectedCode, ...params) {
if (params.length >= 2) {
params[1] = common.mustNotMutateObjectDeep(params[1]);
}
let fh;
try {
fh = await fsPromises.open(dest, 'w+');
@@ -28,6 +31,8 @@ async function testInvalid(dest, expectedCode, ...params) {
}
async function testValid(dest, buffer, options) {
const length = options?.length;
const offset = options?.offset;
let fh;
try {
fh = await fsPromises.open(dest, 'w+');
@@ -38,10 +43,10 @@ async function testValid(dest, buffer, options) {
const readBufCopy = Uint8Array.prototype.slice.call(readResult.buffer);
assert.ok(writeResult.bytesWritten >= readResult.bytesRead);
if (options.length !== undefined && options.length !== null) {
assert.strictEqual(writeResult.bytesWritten, options.length);
if (length !== undefined && length !== null) {
assert.strictEqual(writeResult.bytesWritten, length);
}
if (options.offset === undefined || options.offset === 0) {
if (offset === undefined || offset === 0) {
assert.deepStrictEqual(writeBufCopy, readBufCopy);
}
assert.deepStrictEqual(writeResult.buffer, readResult.buffer);
@@ -54,6 +59,8 @@ async function testValid(dest, buffer, options) {
// Test if first argument is not wrongly interpreted as ArrayBufferView|string
for (const badBuffer of [
undefined, null, true, 42, 42n, Symbol('42'), NaN, [], () => {},
common.mustNotCall(),
common.mustNotMutateObjectDeep({}),
Promise.resolve(new Uint8Array(1)),
{},
{ buffer: 'amNotParam' },
@@ -64,7 +71,7 @@ async function testValid(dest, buffer, options) {
{ toString() { return 'amObject'; } },
{ [Symbol.toPrimitive]: (hint) => 'amObject' },
]) {
await testInvalid(dest, 'ERR_INVALID_ARG_TYPE', badBuffer, {});
await testInvalid(dest, 'ERR_INVALID_ARG_TYPE', common.mustNotMutateObjectDeep(badBuffer), {});
}
// First argument (buffer or string) is mandatory
@@ -81,6 +88,8 @@ async function testValid(dest, buffer, options) {
// Test compatibility with filehandle.read counterpart
for (const options of [
undefined,
null,
{},
{ length: 1 },
{ position: 5 },
@@ -90,6 +99,6 @@ async function testValid(dest, buffer, options) {
{ position: null },
{ offset: 1 },
]) {
await testValid(dest, buffer, options);
await testValid(dest, buffer, common.mustNotMutateObjectDeep(options));
}
})().then(common.mustCall());

View File

@@ -30,9 +30,9 @@ function testValid(message, ...options) {
testValid('Not passing in any object');
testValid('Passing in a null', null);
testValid('Passing in an empty object', {});
testValid('Passing in an object', {
testValid('Passing in an empty object', common.mustNotMutateObjectDeep({}));
testValid('Passing in an object', common.mustNotMutateObjectDeep({
offset: 0,
length: bufferAsOption.byteLength,
position: 0,
});
}));

View File

@@ -28,7 +28,7 @@ async function testValid(position, allowedErrors = []) {
}, callCount);
fs.read(fd, buffer, offset, length, position, handler);
fs.read(fd, { buffer, offset, length, position }, handler);
fs.read(fd, buffer, { offset, length, position }, handler);
fs.read(fd, buffer, common.mustNotMutateObjectDeep({ offset, length, position }), handler);
}));
});
}
@@ -46,7 +46,7 @@ async function testInvalid(code, position) {
{ code }
);
assert.throws(
() => fs.read(fd, buffer, { offset, length, position }, common.mustNotCall()),
() => fs.read(fd, buffer, common.mustNotMutateObjectDeep({ offset, length, position }), common.mustNotCall()),
{ code }
);
resolve();

View File

@@ -12,14 +12,14 @@ const expected = Buffer.from('xyz\n');
const defaultBufferAsync = Buffer.alloc(16384);
const bufferAsOption = Buffer.allocUnsafe(expected.byteLength);
read(fd, {})
read(fd, common.mustNotMutateObjectDeep({}))
.then(function({ bytesRead, buffer }) {
assert.strictEqual(bytesRead, expected.byteLength);
assert.deepStrictEqual(defaultBufferAsync.byteLength, buffer.byteLength);
})
.then(common.mustCall());
read(fd, bufferAsOption, { position: 0 })
read(fd, bufferAsOption, common.mustNotMutateObjectDeep({ position: 0 }))
.then(function({ bytesRead, buffer }) {
assert.strictEqual(bytesRead, expected.byteLength);
assert.deepStrictEqual(bufferAsOption.byteLength, buffer.byteLength);

View File

@@ -98,7 +98,7 @@ test1({
});
{
const file = fs.createReadStream(fn, { encoding: 'utf8' });
const file = fs.createReadStream(fn, common.mustNotMutateObjectDeep({ encoding: 'utf8' }));
file.length = 0;
file.on('data', function(data) {
assert.strictEqual(typeof data, 'string');
@@ -119,7 +119,7 @@ test1({
{
const file =
fs.createReadStream(rangeFile, { bufferSize: 1, start: 1, end: 2 });
fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ bufferSize: 1, start: 1, end: 2 }));
let contentRead = '';
file.on('data', function(data) {
contentRead += data.toString('utf-8');
@@ -130,7 +130,7 @@ test1({
}
{
const file = fs.createReadStream(rangeFile, { bufferSize: 1, start: 1 });
const file = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ bufferSize: 1, start: 1 }));
file.data = '';
file.on('data', function(data) {
file.data += data.toString('utf-8');
@@ -142,7 +142,7 @@ test1({
{
// Ref: https://github.com/nodejs/node-v0.x-archive/issues/2320
const file = fs.createReadStream(rangeFile, { bufferSize: 1.23, start: 1 });
const file = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ bufferSize: 1.23, start: 1 }));
file.data = '';
file.on('data', function(data) {
file.data += data.toString('utf-8');
@@ -154,7 +154,7 @@ test1({
assert.throws(
() => {
fs.createReadStream(rangeFile, { start: 10, end: 2 });
fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ start: 10, end: 2 }));
},
{
code: 'ERR_OUT_OF_RANGE',
@@ -164,7 +164,7 @@ assert.throws(
});
{
const stream = fs.createReadStream(rangeFile, { start: 0, end: 0 });
const stream = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ start: 0, end: 0 }));
stream.data = '';
stream.on('data', function(chunk) {
@@ -178,7 +178,7 @@ assert.throws(
{
// Verify that end works when start is not specified.
const stream = new fs.createReadStream(rangeFile, { end: 1 });
const stream = new fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ end: 1 }));
stream.data = '';
stream.on('data', function(chunk) {
@@ -199,7 +199,7 @@ if (!common.isWindows) {
const mkfifoResult = child_process.spawnSync('mkfifo', [filename]);
if (!mkfifoResult.error) {
child_process.exec(`echo "xyz foobar" > '${filename}'`);
const stream = new fs.createReadStream(filename, { end: 1 });
const stream = new fs.createReadStream(filename, common.mustNotMutateObjectDeep({ end: 1 }));
stream.data = '';
stream.on('data', function(chunk) {
@@ -223,7 +223,7 @@ if (!common.isWindows) {
}
{
let file = fs.createReadStream(rangeFile, { autoClose: false });
let file = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ autoClose: false }));
let data = '';
file.on('data', function(chunk) { data += chunk; });
file.on('end', common.mustCall(function() {
@@ -237,7 +237,7 @@ if (!common.isWindows) {
function fileNext() {
// This will tell us if the fd is usable again or not.
file = fs.createReadStream(null, { fd: file.fd, start: 0 });
file = fs.createReadStream(null, common.mustNotMutateObjectDeep({ fd: file.fd, start: 0 }));
file.data = '';
file.on('data', function(data) {
file.data += data;
@@ -254,7 +254,7 @@ if (!common.isWindows) {
{
// Just to make sure autoClose won't close the stream because of error.
const file = fs.createReadStream(null, { fd: 13337, autoClose: false });
const file = fs.createReadStream(null, common.mustNotMutateObjectDeep({ fd: 13337, autoClose: false }));
file.on('data', common.mustNotCall());
file.on('error', common.mustCall());
process.on('exit', function() {

View File

@@ -1,6 +1,6 @@
'use strict';
require('../common');
const { mustNotMutateObjectDeep } = require('../common');
const fixtures = require('../common/fixtures');
const fs = require('fs');
const assert = require('assert');
@@ -53,5 +53,5 @@ for (const options of [
new String('4444'),
[4, 4, 4, 4],
]) {
runTest(Buffer.allocUnsafe(expected.length), options);
runTest(Buffer.allocUnsafe(expected.length), mustNotMutateObjectDeep(options));
}

View File

@@ -1,4 +1,4 @@
import '../common/index.mjs';
import * as common from '../common/index.mjs';
import * as fixtures from '../common/fixtures.mjs';
import fs from 'fs';
import assert from 'assert';
@@ -18,7 +18,7 @@ function testValid(position, allowedErrors = []) {
try {
fdSync = fs.openSync(filepath, 'r');
fs.readSync(fdSync, buffer, offset, length, position);
fs.readSync(fdSync, buffer, { offset, length, position });
fs.readSync(fdSync, buffer, common.mustNotMutateObjectDeep({ offset, length, position }));
} catch (err) {
if (!allowedErrors.includes(err.code)) {
assert.fail(err);
@@ -37,7 +37,7 @@ function testInvalid(code, position, internalCatch = false) {
{ code }
);
assert.throws(
() => fs.readSync(fdSync, buffer, { offset, length, position }),
() => fs.readSync(fdSync, buffer, common.mustNotMutateObjectDeep({ offset, length, position })),
{ code }
);
} finally {

View File

@@ -16,14 +16,14 @@ tmpdir.refresh();
fs.readFile(
emptyFile,
// With `a+` the file is created if it does not exist
{ encoding: 'utf8', flag: 'a+' },
common.mustNotMutateObjectDeep({ encoding: 'utf8', flag: 'a+' }),
common.mustCall((err, data) => { assert.strictEqual(data, ''); })
);
fs.readFile(
emptyFile,
// Like `a+` but fails if the path exists.
{ encoding: 'utf8', flag: 'ax+' },
common.mustNotMutateObjectDeep({ encoding: 'utf8', flag: 'ax+' }),
common.mustCall((err, data) => { assert.strictEqual(err.code, 'EEXIST'); })
);
}
@@ -34,7 +34,7 @@ tmpdir.refresh();
fs.readFile(
willBeCreated,
// With `a+` the file is created if it does not exist
{ encoding: 'utf8', flag: 'a+' },
common.mustNotMutateObjectDeep({ encoding: 'utf8', flag: 'a+' }),
common.mustCall((err, data) => { assert.strictEqual(data, ''); })
);
}
@@ -45,7 +45,7 @@ tmpdir.refresh();
fs.readFile(
willNotBeCreated,
// Default flag is `r`. An exception occurs if the file does not exist.
{ encoding: 'utf8' },
common.mustNotMutateObjectDeep({ encoding: 'utf8' }),
common.mustCall((err, data) => { assert.strictEqual(err.code, 'ENOENT'); })
);
}

View File

@@ -22,14 +22,14 @@ const isGitPresent = (() => {
function gitInit(gitDirectory) {
fs.mkdirSync(gitDirectory);
execSync('git init', { cwd: gitDirectory });
execSync('git init', common.mustNotMutateObjectDeep({ cwd: gitDirectory }));
}
function makeNonEmptyDirectory(depth, files, folders, dirname, createSymLinks) {
fs.mkdirSync(dirname, { recursive: true });
fs.mkdirSync(dirname, common.mustNotMutateObjectDeep({ recursive: true }));
fs.writeFileSync(path.join(dirname, 'text.txt'), 'hello', 'utf8');
const options = { flag: 'wx' };
const options = common.mustNotMutateObjectDeep({ flag: 'wx' });
for (let f = files; f > 0; f--) {
fs.writeFileSync(path.join(dirname, `f-${depth}-${f}`), '', options);
@@ -80,11 +80,11 @@ function removeAsync(dir) {
assert.strictEqual(err.syscall, 'rm');
// Removal should fail without the recursive option set to true.
fs.rm(dir, { recursive: false }, common.mustCall((err) => {
fs.rm(dir, common.mustNotMutateObjectDeep({ recursive: false }), common.mustCall((err) => {
assert.strictEqual(err.syscall, 'rm');
// Recursive removal should succeed.
fs.rm(dir, { recursive: true }, common.mustSucceed(() => {
fs.rm(dir, common.mustNotMutateObjectDeep({ recursive: true }), common.mustSucceed(() => {
// Attempted removal should fail now because the directory is gone.
fs.rm(dir, common.mustCall((err) => {
@@ -120,7 +120,7 @@ function removeAsync(dir) {
// Should fail if target does not exist
fs.rm(
path.join(tmpdir.path, 'noexist.txt'),
{ recursive: true },
common.mustNotMutateObjectDeep({ recursive: true }),
common.mustCall((err) => {
assert.strictEqual(err.code, 'ENOENT');
})
@@ -129,12 +129,12 @@ function removeAsync(dir) {
// Should delete a file
const filePath = path.join(tmpdir.path, 'rm-async-file.txt');
fs.writeFileSync(filePath, '');
fs.rm(filePath, { recursive: true }, common.mustCall((err) => {
fs.rm(filePath, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall((err) => {
try {
assert.strictEqual(err, null);
assert.strictEqual(fs.existsSync(filePath), false);
} finally {
fs.rmSync(filePath, { force: true });
fs.rmSync(filePath, common.mustNotMutateObjectDeep({ force: true }));
}
}));
}
@@ -144,7 +144,7 @@ function removeAsync(dir) {
if (isGitPresent) {
const gitDirectory = nextDirPath();
gitInit(gitDirectory);
fs.rm(gitDirectory, { recursive: true }, common.mustSucceed(() => {
fs.rm(gitDirectory, common.mustNotMutateObjectDeep({ recursive: true }), common.mustSucceed(() => {
assert.strictEqual(fs.existsSync(gitDirectory), false);
}));
}
@@ -159,12 +159,12 @@ if (isGitPresent) {
fs.rmSync(dir);
}, { syscall: 'rm' });
assert.throws(() => {
fs.rmSync(dir, { recursive: false });
fs.rmSync(dir, common.mustNotMutateObjectDeep({ recursive: false }));
}, { syscall: 'rm' });
// Should fail if target does not exist
assert.throws(() => {
fs.rmSync(path.join(tmpdir.path, 'noexist.txt'), { recursive: true });
fs.rmSync(path.join(tmpdir.path, 'noexist.txt'), common.mustNotMutateObjectDeep({ recursive: true }));
}, {
code: 'ENOENT',
name: 'Error',
@@ -176,9 +176,9 @@ if (isGitPresent) {
fs.writeFileSync(filePath, '');
try {
fs.rmSync(filePath, { recursive: true });
fs.rmSync(filePath, common.mustNotMutateObjectDeep({ recursive: true }));
} finally {
fs.rmSync(filePath, { force: true });
fs.rmSync(filePath, common.mustNotMutateObjectDeep({ force: true }));
}
// Should accept URL
@@ -186,9 +186,9 @@ if (isGitPresent) {
fs.writeFileSync(fileURL, '');
try {
fs.rmSync(fileURL, { recursive: true });
fs.rmSync(fileURL, common.mustNotMutateObjectDeep({ recursive: true }));
} finally {
fs.rmSync(fileURL, { force: true });
fs.rmSync(fileURL, common.mustNotMutateObjectDeep({ force: true }));
}
// Recursive removal should succeed.
@@ -203,7 +203,7 @@ if (isGitPresent) {
if (isGitPresent) {
const gitDirectory = nextDirPath();
gitInit(gitDirectory);
fs.rmSync(gitDirectory, { recursive: true });
fs.rmSync(gitDirectory, common.mustNotMutateObjectDeep({ recursive: true }));
assert.strictEqual(fs.existsSync(gitDirectory), false);
}
@@ -214,12 +214,12 @@ if (isGitPresent) {
// Removal should fail without the recursive option set to true.
await assert.rejects(fs.promises.rm(dir), { syscall: 'rm' });
await assert.rejects(fs.promises.rm(dir, { recursive: false }), {
await assert.rejects(fs.promises.rm(dir, common.mustNotMutateObjectDeep({ recursive: false })), {
syscall: 'rm'
});
// Recursive removal should succeed.
await fs.promises.rm(dir, { recursive: true });
await fs.promises.rm(dir, common.mustNotMutateObjectDeep({ recursive: true }));
// Attempted removal should fail now because the directory is gone.
await assert.rejects(fs.promises.rm(dir), { syscall: 'stat' });
@@ -235,16 +235,16 @@ if (isGitPresent) {
});
// Should not fail if target does not exist and force option is true
await fs.promises.rm(path.join(tmpdir.path, 'noexist.txt'), { force: true });
await fs.promises.rm(path.join(tmpdir.path, 'noexist.txt'), common.mustNotMutateObjectDeep({ force: true }));
// Should delete file
const filePath = path.join(tmpdir.path, 'rm-promises-file.txt');
fs.writeFileSync(filePath, '');
try {
await fs.promises.rm(filePath, { recursive: true });
await fs.promises.rm(filePath, common.mustNotMutateObjectDeep({ recursive: true }));
} finally {
fs.rmSync(filePath, { force: true });
fs.rmSync(filePath, common.mustNotMutateObjectDeep({ force: true }));
}
// Should accept URL
@@ -252,9 +252,9 @@ if (isGitPresent) {
fs.writeFileSync(fileURL, '');
try {
await fs.promises.rm(fileURL, { recursive: true });
await fs.promises.rm(fileURL, common.mustNotMutateObjectDeep({ recursive: true }));
} finally {
fs.rmSync(fileURL, { force: true });
fs.rmSync(fileURL, common.mustNotMutateObjectDeep({ force: true }));
}
})().then(common.mustCall());
@@ -264,7 +264,7 @@ if (isGitPresent) {
(async () => {
const gitDirectory = nextDirPath();
gitInit(gitDirectory);
await fs.promises.rm(gitDirectory, { recursive: true });
await fs.promises.rm(gitDirectory, common.mustNotMutateObjectDeep({ recursive: true }));
assert.strictEqual(fs.existsSync(gitDirectory), false);
})().then(common.mustCall());
}
@@ -379,11 +379,11 @@ if (isGitPresent) {
const dirname = nextDirPath();
const filePath = path.join(dirname, 'text.txt');
try {
fs.mkdirSync(dirname, { recursive: true });
fs.mkdirSync(dirname, common.mustNotMutateObjectDeep({ recursive: true }));
fs.writeFileSync(filePath, 'hello');
const code = makeDirectoryReadOnly(dirname, 0o444);
assert.throws(() => {
fs.rmSync(filePath, { force: true });
fs.rmSync(filePath, common.mustNotMutateObjectDeep({ force: true }));
}, {
code,
name: 'Error',
@@ -397,7 +397,7 @@ if (isGitPresent) {
// Check endless recursion.
// https://github.com/nodejs/node/issues/34580
const dirname = nextDirPath();
fs.mkdirSync(dirname, { recursive: true });
fs.mkdirSync(dirname, common.mustNotMutateObjectDeep({ recursive: true }));
const root = fs.mkdtempSync(path.join(dirname, 'fs-'));
const middle = path.join(root, 'middle');
fs.mkdirSync(middle);
@@ -406,7 +406,7 @@ if (isGitPresent) {
const code = makeDirectoryReadOnly(middle, 0o555);
try {
assert.throws(() => {
fs.rmSync(root, { recursive: true });
fs.rmSync(root, common.mustNotMutateObjectDeep({ recursive: true }));
}, {
code,
name: 'Error',

View File

@@ -96,7 +96,7 @@ function verifyStats(bigintStats, numStats, allowableDelta) {
const runSyncTest = (func, arg) => {
const startTime = process.hrtime.bigint();
const bigintStats = func(arg, { bigint: true });
const bigintStats = func(arg, common.mustNotMutateObjectDeep({ bigint: true }));
const numStats = func(arg);
const endTime = process.hrtime.bigint();
const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);
@@ -127,7 +127,7 @@ if (!common.isWindows) {
() => fs.statSync('does_not_exist'),
{ code: 'ENOENT' });
assert.strictEqual(
fs.statSync('does_not_exist', { throwIfNoEntry: false }),
fs.statSync('does_not_exist', common.mustNotMutateObjectDeep({ throwIfNoEntry: false })),
undefined);
}
@@ -136,7 +136,7 @@ if (!common.isWindows) {
() => fs.lstatSync('does_not_exist'),
{ code: 'ENOENT' });
assert.strictEqual(
fs.lstatSync('does_not_exist', { throwIfNoEntry: false }),
fs.lstatSync('does_not_exist', common.mustNotMutateObjectDeep({ throwIfNoEntry: false })),
undefined);
}
@@ -145,13 +145,13 @@ if (!common.isWindows) {
() => fs.fstatSync(9999),
{ code: 'EBADF' });
assert.throws(
() => fs.fstatSync(9999, { throwIfNoEntry: false }),
() => fs.fstatSync(9999, common.mustNotMutateObjectDeep({ throwIfNoEntry: false })),
{ code: 'EBADF' });
}
const runCallbackTest = (func, arg, done) => {
const startTime = process.hrtime.bigint();
func(arg, { bigint: true }, common.mustCall((err, bigintStats) => {
func(arg, common.mustNotMutateObjectDeep({ bigint: true }), common.mustCall((err, bigintStats) => {
func(arg, common.mustCall((err, numStats) => {
const endTime = process.hrtime.bigint();
const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);
@@ -183,7 +183,7 @@ if (!common.isWindows) {
const runPromiseTest = async (func, arg) => {
const startTime = process.hrtime.bigint();
const bigintStats = await func(arg, { bigint: true });
const bigintStats = await func(arg, common.mustNotMutateObjectDeep({ bigint: true }));
const numStats = await func(arg);
const endTime = process.hrtime.bigint();
const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);
@@ -206,7 +206,7 @@ if (!common.isWindows) {
const filename = getFilename();
const handle = await promiseFs.open(filename, 'r');
const startTime = process.hrtime.bigint();
const bigintStats = await handle.stat({ bigint: true });
const bigintStats = await handle.stat(common.mustNotMutateObjectDeep({ bigint: true }));
const numStats = await handle.stat();
const endTime = process.hrtime.bigint();
const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);

View File

@@ -1,5 +1,5 @@
'use strict';
require('../common');
const { mustNotMutateObjectDeep } = require('../common');
const assert = require('assert');
const fs = require('fs');
@@ -9,7 +9,7 @@ const fs = require('fs');
assert.throws(
() => {
fs.createReadStream(null, { fd });
fs.createReadStream(null, mustNotMutateObjectDeep({ fd }));
},
{
code: 'ERR_INVALID_ARG_TYPE',
@@ -18,7 +18,7 @@ const fs = require('fs');
assert.throws(
() => {
fs.createWriteStream(null, { fd });
fs.createWriteStream(null, mustNotMutateObjectDeep({ fd }));
},
{
code: 'ERR_INVALID_ARG_TYPE',

View File

@@ -18,13 +18,16 @@ const buffer = Buffer.from('zyx');
function testInvalidCb(fd, expectedCode, buffer, options, callback) {
assert.throws(
() => fs.write(fd, buffer, options, common.mustNotCall()),
() => fs.write(fd, buffer, common.mustNotMutateObjectDeep(options), common.mustNotCall()),
{ code: expectedCode }
);
callback(0);
}
function testValidCb(buffer, options, index, callback) {
options = common.mustNotMutateObjectDeep(options);
const length = options?.length;
const offset = options?.offset;
const dest = path.resolve(tmpdir.path, `rwopt_valid_${index}`);
fs.open(dest, 'w+', common.mustSucceed((fd) => {
fs.write(fd, buffer, options, common.mustSucceed((bytesWritten, bufferWritten) => {
@@ -34,10 +37,10 @@ function testValidCb(buffer, options, index, callback) {
const readBufCopy = Uint8Array.prototype.slice.call(bufferRead);
assert.ok(bytesWritten >= bytesRead);
if (options.length !== undefined && options.length !== null) {
assert.strictEqual(bytesWritten, options.length);
if (length !== undefined && length !== null) {
assert.strictEqual(bytesWritten, length);
}
if (options.offset === undefined || options.offset === 0) {
if (offset === undefined || offset === 0) {
assert.deepStrictEqual(writeBufCopy, readBufCopy);
}
assert.deepStrictEqual(bufferWritten, bufferRead);
@@ -56,6 +59,8 @@ async function runTests(fd) {
for (const badBuffer of [
undefined, null, true, 42, 42n, Symbol('42'), NaN, [], () => {},
Promise.resolve(new Uint8Array(1)),
common.mustNotCall(),
common.mustNotMutateObjectDeep({}),
{},
{ buffer: 'amNotParam' },
{ string: 'amNotParam' },
@@ -81,9 +86,13 @@ async function runTests(fd) {
await testInvalid(fd, 'ERR_OUT_OF_RANGE', buffer, { offset: -1 });
await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, { offset: false });
await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, { offset: true });
await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, true);
await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, '42');
await testInvalid(fd, 'ERR_INVALID_ARG_TYPE', buffer, Symbol('42'));
// Test compatibility with fs.read counterpart
for (const [ index, options ] of [
null,
{},
{ length: 1 },
{ position: 5 },

View File

@@ -1,6 +1,6 @@
'use strict';
require('../common');
const common = require('../common');
// This test ensures that fs.writeSync accepts "named parameters" object
// and doesn't interpret objects as strings
@@ -16,6 +16,9 @@ const dest = path.resolve(tmpdir.path, 'tmp.txt');
const buffer = Buffer.from('zyx');
function testInvalid(dest, expectedCode, ...bufferAndOptions) {
if (bufferAndOptions.length >= 2) {
bufferAndOptions[1] = common.mustNotMutateObjectDeep(bufferAndOptions[1]);
}
let fd;
try {
fd = fs.openSync(dest, 'w+');
@@ -28,6 +31,7 @@ function testInvalid(dest, expectedCode, ...bufferAndOptions) {
}
function testValid(dest, buffer, options) {
const length = options?.length;
let fd;
try {
fd = fs.openSync(dest, 'w+');
@@ -35,8 +39,8 @@ function testValid(dest, buffer, options) {
const bytesRead = fs.readSync(fd, buffer, options);
assert.ok(bytesWritten >= bytesRead);
if (options.length !== undefined && options.length !== null) {
assert.strictEqual(bytesWritten, options.length);
if (length !== undefined && length !== null) {
assert.strictEqual(bytesWritten, length);
}
} finally {
if (fd != null) fs.closeSync(fd);
@@ -47,6 +51,8 @@ function testValid(dest, buffer, options) {
// Test if second argument is not wrongly interpreted as string or options
for (const badBuffer of [
undefined, null, true, 42, 42n, Symbol('42'), NaN, [], () => {},
common.mustNotCall(),
common.mustNotMutateObjectDeep({}),
{},
{ buffer: 'amNotParam' },
{ string: 'amNotParam' },
@@ -58,7 +64,7 @@ function testValid(dest, buffer, options) {
{ toString() { return 'amObject'; } },
{ [Symbol.toPrimitive]: (hint) => 'amObject' },
]) {
testInvalid(dest, 'ERR_INVALID_ARG_TYPE', badBuffer);
testInvalid(dest, 'ERR_INVALID_ARG_TYPE', common.mustNotMutateObjectDeep(badBuffer));
}
// First argument (buffer or string) is mandatory
@@ -75,6 +81,8 @@ function testValid(dest, buffer, options) {
// Test compatibility with fs.readSync counterpart with reused options
for (const options of [
undefined,
null,
{},
{ length: 1 },
{ position: 5 },
@@ -84,6 +92,6 @@ function testValid(dest, buffer, options) {
{ position: null },
{ offset: 1 },
]) {
testValid(dest, buffer, options);
testValid(dest, buffer, common.mustNotMutateObjectDeep(options));
}
}