diff --git a/test/common/README.md b/test/common/README.md index 08d7bbb762fbb4..eaed6f41adc63f 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -120,11 +120,33 @@ an expected warning does not have a code then `common.noWarnCode` can be used to indicate this. ### fileExists(pathname) -* pathname [<string>] +* `pathname` [<string>] * return [<boolean>] Checks if `pathname` exists +### fsTest(method, args, options) +* `method` [<string>] +* `args` [<Array>] +* `options` [<Object>] + +Run both `fs[method]()` and `fsPromises[method]()` passing `args`. +`util.callbackify()` is used to convert the `fsPromises` version of the method +into one that takes a callback. The last value in `args` must be a callback that +is expected to run once for each of the two invocations. + +The `options` object may contain a `setup` property that is a function that is +run before each test. This function might refresh the temporary directory if +both tests need to use it, for example. The `options` object may also contain a +`throws` property that is a boolean indicating if the `fs[method]()` function is +expected to throw. The `fsPromises[method]()` function will be expected to +reject. Lastly, the `options` object may contain a `differentFiles` array. If +`differentFiles` is included, then the first element is inserted as the first +argument (typically the path to a file) when testing the callback-based API and +the second element is inserted as the first argument when testing the +Promise-based API. This can be useful when testing APIs that modify the target +file. + ### getArrayBufferViews(buf) * `buf` [<Buffer>] * return [<ArrayBufferView[]>] diff --git a/test/common/index.js b/test/common/index.js index ea77c963aa9af0..ab2a517bad6a21 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -892,3 +892,37 @@ exports.isCPPSymbolsNotMapped = exports.isWindows || exports.isAIX || exports.isLinuxPPCBE || exports.isFreeBSD; + +// Run test for both fs.method and fsPromises.method with args. +// The last value in args must be a callback that is expected to run once for +// each call to the method named in `method`. +exports.fsTest = (method, args, options = {}) => { + const fsPromises = fs.promises; + + if (options.differentFiles) + args.unshift(options.differentFiles[0]); + + if (options.setup) + options.setup(); + const checkResults = args.pop(); + + const wrappedCheck = (...callbackArgs) => { + checkResults(...callbackArgs); + if (options.setup) + options.setup(); + const callbackified = util.callbackify(fsPromises[method]); + if (options.differentFiles) + args[0] = options.differentFiles[1]; + callbackified(...args, exports.mustCall(checkResults)); + return true; + }; + + if (options.throws) { + assert.throws( + () => { fs[method](...args, exports.mustNotCall()); }, + wrappedCheck + ); + } else { + fs[method](...args, exports.mustCall(wrappedCheck)); + } +}; diff --git a/test/parallel/test-fs-access.js b/test/parallel/test-fs-access.js index 20448ffde6c6ea..7b632394f54596 100644 --- a/test/parallel/test-fs-access.js +++ b/test/parallel/test-fs-access.js @@ -62,17 +62,17 @@ assert.strictEqual(typeof fs.R_OK, 'number'); assert.strictEqual(typeof fs.W_OK, 'number'); assert.strictEqual(typeof fs.X_OK, 'number'); -fs.access(__filename, common.mustCall(assert.ifError)); -fs.access(__filename, fs.R_OK, common.mustCall(assert.ifError)); -fs.access(readOnlyFile, fs.F_OK | fs.R_OK, common.mustCall(assert.ifError)); +common.fsTest('access', [__filename, assert.ifError]); +common.fsTest('access', [__filename, fs.R_OK, assert.ifError]); +common.fsTest('access', [readOnlyFile, fs.F_OK | fs.R_OK, assert.ifError]); -fs.access(doesNotExist, common.mustCall((err) => { +common.fsTest('access', [doesNotExist, (err) => { assert.notStrictEqual(err, null, 'error should exist'); assert.strictEqual(err.code, 'ENOENT'); assert.strictEqual(err.path, doesNotExist); -})); +}]); -fs.access(readOnlyFile, fs.W_OK, common.mustCall(function(err) { +common.fsTest('access', [readOnlyFile, fs.W_OK, function(err) { assert.strictEqual(this, undefined); if (hasWriteAccessForReadonlyFile) { assert.ifError(err); @@ -80,20 +80,19 @@ fs.access(readOnlyFile, fs.W_OK, common.mustCall(function(err) { assert.notStrictEqual(err, null, 'error should exist'); assert.strictEqual(err.path, readOnlyFile); } -})); +}]); -common.expectsError( - () => { - fs.access(100, fs.F_OK, common.mustNotCall()); - }, - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError, - message: 'The "path" argument must be one of type string, Buffer, or URL.' + - ' Received type number' - } -); +{ + const expectedError = (e) => { + assert.strictEqual(e.code, 'ERR_INVALID_ARG_TYPE'); + assert(e instanceof TypeError); + }; + + common.fsTest('access', [100, fs.F_OK, expectedError], { throws: true }); +} +// These tests do not use common.fsTest because the equivalent of a callback +// is not required in fsPromises.access(). You know, because: Promises. common.expectsError( () => { fs.access(__filename, fs.F_OK); diff --git a/test/parallel/test-fs-append-file.js b/test/parallel/test-fs-append-file.js index 29ae1b2f3b9e9a..9c4497ccb123a0 100644 --- a/test/parallel/test-fs-append-file.js +++ b/test/parallel/test-fs-append-file.js @@ -23,11 +23,12 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); -const join = require('path').join; +const fsPromises = fs.promises; +const { join } = require('path'); +const util = require('util'); const tmpdir = require('../common/tmpdir'); - -const filename = join(tmpdir.path, 'append.txt'); +tmpdir.refresh(); const currentFileData = 'ABCD'; @@ -40,122 +41,114 @@ const s = '南越国是前203年至前111年存在于岭南地区的一个国家 '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; -let ncallbacks = 0; - -tmpdir.refresh(); - // test that empty file will be created and have content added -fs.appendFile(filename, s, function(e) { - assert.ifError(e); - - ncallbacks++; +{ + const filename = join(tmpdir.path, 'append.txt'); - fs.readFile(filename, function(e, buffer) { + common.fsTest('appendFile', [filename, s, function(e) { assert.ifError(e); - ncallbacks++; - assert.strictEqual(Buffer.byteLength(s), buffer.length); - }); -}); -// test that appends data to a non empty file -const filename2 = join(tmpdir.path, 'append2.txt'); -fs.writeFileSync(filename2, currentFileData); + const buffer = fs.readFileSync(filename); + assert.strictEqual(buffer.length, Buffer.byteLength(s)); + fs.unlinkSync(filename); + }]); +} -fs.appendFile(filename2, s, function(e) { - assert.ifError(e); +// test that appends data to a non empty file +{ + const filename = join(tmpdir.path, 'append2.txt'); - ncallbacks++; + const setup = () => { + fs.writeFileSync(filename, currentFileData); + }; - fs.readFile(filename2, function(e, buffer) { + common.fsTest('appendFile', [filename, s, function(e) { assert.ifError(e); - ncallbacks++; - assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, - buffer.length); - }); -}); -// test that appendFile accepts buffers -const filename3 = join(tmpdir.path, 'append3.txt'); -fs.writeFileSync(filename3, currentFileData); + const buffer = fs.readFileSync(filename); + assert.strictEqual(buffer.length, + Buffer.byteLength(s) + currentFileData.length); + }], { setup: setup }); +} -const buf = Buffer.from(s, 'utf8'); +// test that appendFile accepts buffers +{ + const filename = join(tmpdir.path, 'append3.txt'); -fs.appendFile(filename3, buf, function(e) { - assert.ifError(e); + const setup = () => { + fs.writeFileSync(filename, currentFileData); + }; - ncallbacks++; + const buf = Buffer.from(s, 'utf8'); - fs.readFile(filename3, function(e, buffer) { + common.fsTest('appendFile', [filename, buf, function(e) { assert.ifError(e); - ncallbacks++; - assert.strictEqual(buf.length + currentFileData.length, buffer.length); - }); -}); - -// test that appendFile accepts numbers. -const filename4 = join(tmpdir.path, 'append4.txt'); -fs.writeFileSync(filename4, currentFileData); -const m = 0o600; -fs.appendFile(filename4, n, { mode: m }, function(e) { - assert.ifError(e); + const buffer = fs.readFileSync(filename); + assert.strictEqual(buffer.length, buf.length + currentFileData.length); + }], { setup: setup }); +} - ncallbacks++; +// test that appendFile accepts numbers. +{ + const filename = join(tmpdir.path, 'append4.txt'); - // windows permissions aren't unix - if (!common.isWindows) { - const st = fs.statSync(filename4); - assert.strictEqual(st.mode & 0o700, m); - } + const setup = () => { fs.writeFileSync(filename, currentFileData); }; - fs.readFile(filename4, function(e, buffer) { + const m = 0o600; + common.fsTest('appendFile', [filename, n, { mode: m }, function(e) { assert.ifError(e); - ncallbacks++; - assert.strictEqual(Buffer.byteLength(String(n)) + currentFileData.length, - buffer.length); - }); -}); - -// test that appendFile accepts file descriptors -const filename5 = join(tmpdir.path, 'append5.txt'); -fs.writeFileSync(filename5, currentFileData); -fs.open(filename5, 'a+', function(e, fd) { - assert.ifError(e); - - ncallbacks++; - - fs.appendFile(fd, s, function(e) { - assert.ifError(e); + // windows permissions aren't unix + if (!common.isWindows) { + const st = fs.statSync(filename); + assert.strictEqual(st.mode & 0o700, m); + } - ncallbacks++; + const buffer = fs.readFileSync(filename); + assert.strictEqual(buffer.length, + Buffer.byteLength(String(n)) + currentFileData.length); + }], { setup: setup }); +} - fs.close(fd, function(e) { +// test that appendFile accepts file descriptors +{ + const filename = join(tmpdir.path, 'append5a.txt'); + const otherFilename = join(tmpdir.path, 'append5b.txt'); + + fs.writeFileSync(filename, currentFileData); + fs.writeFileSync(otherFilename, currentFileData); + + const runTest = (err, fd) => { + assert.ifError(err); + + let appendFile, close; + if (typeof fd === 'number') { + appendFile = fs.appendFile; + close = fs.close.bind(fs, fd); + } else { + appendFile = util.callbackify(fsPromises.appendFile); + close = util.callbackify(fd.close.bind(fd)); + } + + appendFile(fd, s, common.mustCall((e) => { assert.ifError(e); - - ncallbacks++; - - fs.readFile(filename5, function(e, buffer) { + close(common.mustCall((e) => { assert.ifError(e); - - ncallbacks++; - assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, - buffer.length); - }); - }); - }); -}); + const buffer = fs.readFileSync(filename); + assert.strictEqual(buffer.length, + Buffer.byteLength(s) + currentFileData.length); + })); + })); + }; + + common.fsTest( + 'open', + ['a+', runTest], + { differentFiles: [filename, otherFilename] } + ); +} assert.throws( () => fs.appendFile(join(tmpdir.path, 'append6.txt'), console.log), { code: 'ERR_INVALID_CALLBACK' }); - -process.on('exit', function() { - assert.strictEqual(12, ncallbacks); - - fs.unlinkSync(filename); - fs.unlinkSync(filename2); - fs.unlinkSync(filename3); - fs.unlinkSync(filename4); - fs.unlinkSync(filename5); -}); diff --git a/test/parallel/test-fs-assert-encoding-error.js b/test/parallel/test-fs-assert-encoding-error.js index e50a99d751ef62..9feb8fc41cf1d2 100644 --- a/test/parallel/test-fs-assert-encoding-error.js +++ b/test/parallel/test-fs-assert-encoding-error.js @@ -7,43 +7,41 @@ const options = 'test'; const expectedError = common.expectsError({ code: 'ERR_INVALID_OPT_VALUE_ENCODING', type: TypeError, -}, 17); +}, 24); -assert.throws(() => { - fs.readFile('path', options, common.mustNotCall()); -}, expectedError); +common.fsTest('readFile', ['path', options, expectedError], { throws: true }); assert.throws(() => { fs.readFileSync('path', options); }, expectedError); -assert.throws(() => { - fs.readdir('path', options, common.mustNotCall()); -}, expectedError); +common.fsTest('readdir', ['path', options, expectedError], { throws: true }); assert.throws(() => { fs.readdirSync('path', options); }, expectedError); -assert.throws(() => { - fs.readlink('path', options, common.mustNotCall()); -}, expectedError); +common.fsTest('readlink', ['path', options, expectedError], { throws: true }); assert.throws(() => { fs.readlinkSync('path', options); }, expectedError); -assert.throws(() => { - fs.writeFile('path', 'data', options, common.mustNotCall()); -}, expectedError); +common.fsTest( + 'writeFile', + ['path', 'data', options, expectedError], + { throws: true } +); assert.throws(() => { fs.writeFileSync('path', 'data', options); }, expectedError); -assert.throws(() => { - fs.appendFile('path', 'data', options, common.mustNotCall()); -}, expectedError); +common.fsTest( + 'appendFile', + ['path', 'data', options, expectedError], + { throws: true } +); assert.throws(() => { fs.appendFileSync('path', 'data', options); @@ -53,17 +51,13 @@ assert.throws(() => { fs.watch('path', options, common.mustNotCall()); }, expectedError); -assert.throws(() => { - fs.realpath('path', options, common.mustNotCall()); -}, expectedError); +common.fsTest('realpath', ['path', options, expectedError], { throws: true }); assert.throws(() => { fs.realpathSync('path', options); }, expectedError); -assert.throws(() => { - fs.mkdtemp('path', options, common.mustNotCall()); -}, expectedError); +common.fsTest('mkdtemp', ['path', options, expectedError], { throws: true }); assert.throws(() => { fs.mkdtempSync('path', options); diff --git a/test/parallel/test-fs-buffer.js b/test/parallel/test-fs-buffer.js index 1e898d3891339a..627f8fd2f32105 100644 --- a/test/parallel/test-fs-buffer.js +++ b/test/parallel/test-fs-buffer.js @@ -9,14 +9,21 @@ const path = require('path'); const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); -fs.access(Buffer.from(tmpdir.path), common.mustCall(assert.ifError)); +{ + common.fsTest('access', [Buffer.from(tmpdir.path), assert.ifError]); +} -const buf = Buffer.from(path.join(tmpdir.path, 'a.txt')); -fs.open(buf, 'w+', common.mustCall((err, fd) => { - assert.ifError(err); - assert(fd); - fs.close(fd, common.mustCall(assert.ifError)); -})); +{ + const buf = Buffer.from(path.join(tmpdir.path, 'a.txt')); + common.fsTest('open', [buf, 'w+', (err, fd) => { + assert.ifError(err); + assert(fd); + if (typeof fd === 'number') + fs.close(fd, common.mustCall(assert.ifError)); + else + fd.close().catch((e) => { setTimeout((e) => { throw e; }, 1); }); + }]); +} common.expectsError( () => { @@ -30,18 +37,26 @@ common.expectsError( } ); -const dir = Buffer.from(fixtures.fixturesDir); -fs.readdir(dir, 'hex', common.mustCall((err, hexList) => { - assert.ifError(err); - fs.readdir(dir, common.mustCall((err, stringList) => { +{ + const dir = Buffer.from(fixtures.fixturesDir); + const results = []; + + const check = common.mustCall((results) => { + for (let i = 1; i < results.length; i++) { + assert.deepStrictEqual(results[i], results[0]); + } + }); + + common.fsTest('readdir', [dir, 'hex', (err, hexList) => { + assert.ifError(err); + results.push(hexList.map((val) => Buffer.from(val, 'hex').toString())); + if (results.length > 3) + check(results); + }]); + common.fsTest('readdir', [dir, (err, stringList) => { assert.ifError(err); - stringList.forEach((val, idx) => { - const fromHexList = Buffer.from(hexList[idx], 'hex').toString(); - assert.strictEqual( - fromHexList, - val, - `expected ${val}, got ${fromHexList} by hex decoding ${hexList[idx]}` - ); - }); - })); -})); + results.push(stringList); + if (results.length > 3) + check(results); + }]); +} diff --git a/test/parallel/test-fs-chmod.js b/test/parallel/test-fs-chmod.js index 6727ec2144f2ce..75f860b1a33805 100644 --- a/test/parallel/test-fs-chmod.js +++ b/test/parallel/test-fs-chmod.js @@ -21,9 +21,12 @@ 'use strict'; const common = require('../common'); + const assert = require('assert'); -const path = require('path'); const fs = require('fs'); +const fsPromises = fs.promises; +const path = require('path'); +const util = require('util'); let mode_async; let mode_sync; @@ -74,99 +77,124 @@ if (common.isWindows) { const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); -const file1 = path.join(tmpdir.path, 'a.js'); -const file2 = path.join(tmpdir.path, 'a1.js'); +{ + const file1 = path.join(tmpdir.path, 'a.js'); -// Create file1. -fs.closeSync(fs.openSync(file1, 'w')); + const setup = () => { + // Create file, removing it if it existed previously. + fs.closeSync(fs.openSync(file1, 'w')); + }; -fs.chmod(file1, mode_async.toString(8), common.mustCall((err) => { - assert.ifError(err); + common.fsTest('chmod', [file1, mode_async.toString(8), (err) => { + assert.ifError(err); - if (common.isWindows) { - assert.ok((fs.statSync(file1).mode & 0o777) & mode_async); - } else { - assert.strictEqual(mode_async, fs.statSync(file1).mode & 0o777); - } + if (common.isWindows) { + assert.ok((fs.statSync(file1).mode & 0o777) & mode_async); + } else { + assert.strictEqual(mode_async, fs.statSync(file1).mode & 0o777); + } - fs.chmodSync(file1, mode_sync); - if (common.isWindows) { - assert.ok((fs.statSync(file1).mode & 0o777) & mode_sync); - } else { - assert.strictEqual(mode_sync, fs.statSync(file1).mode & 0o777); - } -})); + fs.chmodSync(file1, mode_sync); + if (common.isWindows) { + assert.ok((fs.statSync(file1).mode & 0o777) & mode_sync); + } else { + assert.strictEqual(mode_sync, fs.statSync(file1).mode & 0o777); + } + }], { setup: setup }); +} -fs.open(file2, 'w', common.mustCall((err, fd) => { - assert.ifError(err); +{ + const file1 = path.join(tmpdir.path, 'b.js'); + const file2 = path.join(tmpdir.path, 'c.js'); - fs.fchmod(fd, mode_async.toString(8), common.mustCall((err) => { + common.fsTest('open', ['w', (err, fd) => { assert.ifError(err); - if (common.isWindows) { - assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_async); + let fchmod, close; + + if (typeof fd === 'number') { + fchmod = fs.fchmod.bind(fs, fd); + close = fs.close.bind(fs, fd); } else { - assert.strictEqual(mode_async, fs.fstatSync(fd).mode & 0o777); + fchmod = util.callbackify(fsPromises.fchmod.bind(fs, fd)); + close = util.callbackify(fd.close.bind(fd)); + fd = fd.fd; } + fchmod(mode_async.toString(8), (err) => { + assert.ifError(err); - common.expectsError( - () => fs.fchmod(fd, {}), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError, - message: 'The "mode" argument must be of type number. ' + - 'Received type object' + if (common.isWindows) { + assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_async); + } else { + assert.strictEqual(mode_async, fs.fstatSync(fd).mode & 0o777); } - ); - fs.fchmodSync(fd, mode_sync); - if (common.isWindows) { - assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_sync); - } else { - assert.strictEqual(mode_sync, fs.fstatSync(fd).mode & 0o777); - } + common.expectsError( + () => fs.fchmod(fd, {}), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "mode" argument must be of type number. ' + + 'Received type object' + } + ); + + fs.fchmodSync(fd, mode_sync); + if (common.isWindows) { + assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_sync); + } else { + assert.strictEqual(mode_sync, fs.fstatSync(fd).mode & 0o777); + } - fs.close(fd, assert.ifError); - })); -})); + close(assert.ifError); + }); + }], { differentFiles: [file1, file2] }); +} // lchmod -if (fs.lchmod) { +{ + const file = path.join(tmpdir.path, 'd.js'); const link = path.join(tmpdir.path, 'symbolic-link'); - fs.symlinkSync(file2, link); + const setup = () => { + fs.closeSync(fs.openSync(file, 'w')); + fs.symlinkSync(file, link); + }; - fs.lchmod(link, mode_async, common.mustCall((err) => { - assert.ifError(err); + if (fs.lchmod) { + common.fsTest('lchmod', [link, mode_async, (err) => { + assert.ifError(err); - assert.strictEqual(mode_async, fs.lstatSync(link).mode & 0o777); + assert.strictEqual(mode_async, fs.lstatSync(link).mode & 0o777); - fs.lchmodSync(link, mode_sync); - assert.strictEqual(mode_sync, fs.lstatSync(link).mode & 0o777); + fs.lchmodSync(link, mode_sync); + assert.strictEqual(mode_sync, fs.lstatSync(link).mode & 0o777); - })); + fs.unlinkSync(link); + }], { setup: setup }); + } } ['', false, null, undefined, {}, []].forEach((input) => { - const errObj = { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError [ERR_INVALID_ARG_TYPE]', - message: 'The "fd" argument must be of type number. ' + - `Received type ${typeof input}` + const checkErr = (e) => { + assert.strictEqual(e.code, 'ERR_INVALID_ARG_TYPE'); + assert(e instanceof TypeError); + assert(e.message.includes(typeof input)); + return true; }; - assert.throws(() => fs.fchmod(input, 0o000), errObj); - assert.throws(() => fs.fchmodSync(input, 0o000), errObj); + common.fsTest('fchmod', [input, 0o000, checkErr], { throws: true }); + assert.throws(() => { fs.fchmodSync(input, 0o000); }, checkErr); }); [false, 1, {}, [], null, undefined].forEach((input) => { - const errObj = { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError [ERR_INVALID_ARG_TYPE]', - message: 'The "path" argument must be one of type string, Buffer, or URL.' + - ` Received type ${typeof input}` + const checkErr = (e) => { + assert.strictEqual(e.code, 'ERR_INVALID_ARG_TYPE'); + assert(e instanceof TypeError); + assert(e.message.includes(typeof input)); + return true; }; - assert.throws(() => fs.chmod(input, 1, common.mustNotCall()), errObj); - assert.throws(() => fs.chmodSync(input, 1), errObj); + common.fsTest('chmod', [input, 1, checkErr], { throws: true }); + assert.throws(() => fs.chmodSync(input, 1), checkErr); }); process.on('exit', function() { diff --git a/test/parallel/test-fs-chown-type-check.js b/test/parallel/test-fs-chown-type-check.js index 897c3e1de2d7e2..e4c740236b189a 100644 --- a/test/parallel/test-fs-chown-type-check.js +++ b/test/parallel/test-fs-chown-type-check.js @@ -1,16 +1,17 @@ 'use strict'; const common = require('../common'); + +const assert = require('assert'); const fs = require('fs'); [false, 1, {}, [], null, undefined].forEach((i) => { - common.expectsError( - () => fs.chown(i, 1, 1, common.mustNotCall()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } - ); + const checkErr = (e) => { + assert.strictEqual(e.code, 'ERR_INVALID_ARG_TYPE'); + assert.ok(e instanceof TypeError); + return true; + }; + common.fsTest('chown', [i, 1, 1, checkErr], { throws: true }); common.expectsError( () => fs.chownSync(i, 1, 1), { @@ -21,20 +22,18 @@ const fs = require('fs'); }); [false, 'test', {}, [], null, undefined].forEach((i) => { - common.expectsError( - () => fs.chown('not_a_file_that_exists', i, 1, common.mustNotCall()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } + const checkErr = (e) => { + assert.strictEqual(e.code, 'ERR_INVALID_ARG_TYPE'); + assert.ok(e instanceof TypeError); + return true; + }; + common.fsTest( + 'chown', ['not_a_file_that_exists', i, 1, checkErr], { throws: true } ); - common.expectsError( - () => fs.chown('not_a_file_that_exists', 1, i, common.mustNotCall()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } + common.fsTest( + 'chown', ['not_a_file_that_exists', 1, i, checkErr], { throws: true } ); + common.expectsError( () => fs.chownSync('not_a_file_that_exists', i, 1), { diff --git a/test/parallel/test-fs-link.js b/test/parallel/test-fs-link.js index d007f4e985b2d5..cb12eadb352494 100644 --- a/test/parallel/test-fs-link.js +++ b/test/parallel/test-fs-link.js @@ -1,42 +1,44 @@ 'use strict'; + const common = require('../common'); const assert = require('assert'); -const path = require('path'); const fs = require('fs'); +const path = require('path'); -const tmpdir = require('../common/tmpdir'); -tmpdir.refresh(); +{ + // Loading tmpdir module here because asynchronous nature of tests means that + // it will be subject to race conditions if used elsewhere in the test file. + const tmpdir = require('../common/tmpdir'); + // test creating and reading hard link + const srcPath = path.join(tmpdir.path, 'hardlink-target.txt'); + const dstPath = path.join(tmpdir.path, 'link1.js'); -// test creating and reading hard link -const srcPath = path.join(tmpdir.path, 'hardlink-target.txt'); -const dstPath = path.join(tmpdir.path, 'link1.js'); -fs.writeFileSync(srcPath, 'hello world'); + function callback(err) { + assert.ifError(err); + const dstContent = fs.readFileSync(dstPath, 'utf8'); + assert.strictEqual(dstContent, 'hello world'); + } -function callback(err) { - assert.ifError(err); - const dstContent = fs.readFileSync(dstPath, 'utf8'); - assert.strictEqual('hello world', dstContent); -} + const args = [srcPath, dstPath, callback]; + + const setup = () => { + tmpdir.refresh(); + fs.writeFileSync(srcPath, 'hello world'); + }; -fs.link(srcPath, dstPath, common.mustCall(callback)); + common.fsTest('link', args, { setup }); +} // test error outputs +const expectedError = (e) => { + assert.strictEqual(e.code, 'ERR_INVALID_ARG_TYPE'); + assert.ok(e instanceof TypeError); +}; + [false, 1, [], {}, null, undefined].forEach((i) => { - common.expectsError( - () => fs.link(i, '', common.mustNotCall()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } - ); - common.expectsError( - () => fs.link('', i, common.mustNotCall()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } - ); + common.fsTest('link', [i, '', expectedError], { throws: true }); + common.fsTest('link', ['', i, expectedError], { throws: true }); common.expectsError( () => fs.linkSync(i, ''), { diff --git a/test/parallel/test-fs-unlink-type-check.js b/test/parallel/test-fs-unlink-type-check.js index 7fe3ce946c89d5..b1a7ba898a3fee 100644 --- a/test/parallel/test-fs-unlink-type-check.js +++ b/test/parallel/test-fs-unlink-type-check.js @@ -1,16 +1,17 @@ 'use strict'; const common = require('../common'); + +const assert = require('assert'); const fs = require('fs'); +const expectedError = (e) => { + assert.strictEqual(e.code, 'ERR_INVALID_ARG_TYPE'); + assert.ok(e instanceof TypeError); +}; + [false, 1, {}, [], null, undefined].forEach((i) => { - common.expectsError( - () => fs.unlink(i, common.mustNotCall()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } - ); + common.fsTest('unlink', [i, expectedError], { throws: true }); common.expectsError( () => fs.unlinkSync(i), { diff --git a/test/sequential/test-fs-readfile-tostring-fail.js b/test/sequential/test-fs-readfile-tostring-fail.js index c5ed8559103d77..81bf3950dbd37e 100644 --- a/test/sequential/test-fs-readfile-tostring-fail.js +++ b/test/sequential/test-fs-readfile-tostring-fail.js @@ -29,20 +29,23 @@ for (let i = 0; i < 201; i++) { } stream.end(); + +function checkResults(err, buf) { + assert.ok(err instanceof Error); + if (err.message !== 'Array buffer allocation failed') { + const stringLengthHex = kStringMaxLength.toString(16); + common.expectsError({ + message: 'Cannot create a string longer than ' + + `0x${stringLengthHex} characters`, + code: 'ERR_STRING_TOO_LONG', + type: Error + })(err); + } + assert.strictEqual(buf, undefined); +} + stream.on('finish', common.mustCall(function() { - fs.readFile(file, 'utf8', common.mustCall(function(err, buf) { - assert.ok(err instanceof Error); - if (err.message !== 'Array buffer allocation failed') { - const stringLengthHex = kStringMaxLength.toString(16); - common.expectsError({ - message: 'Cannot create a string longer than ' + - `0x${stringLengthHex} characters`, - code: 'ERR_STRING_TOO_LONG', - type: Error - })(err); - } - assert.strictEqual(buf, undefined); - })); + common.fsTest('readFile', [file, 'utf8', checkResults]); })); function destroy() {