From 5ecabfcb37891cec8f0bd0d82538938ae6913e74 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sun, 21 Jan 2018 15:26:51 +0800 Subject: [PATCH 1/4] test: improve fs error message test - Reuse error validators for sync and async tests - Validate properties of the errors --- test/parallel/test-fs-error-messages.js | 575 ++++++++++++++---------- 1 file changed, 347 insertions(+), 228 deletions(-) diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index 625b791b0b1a7a..8c7bf682b74b56 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -24,276 +24,395 @@ const common = require('../common'); const fixtures = require('../common/fixtures'); const assert = require('assert'); const fs = require('fs'); -const fn = fixtures.path('non-existent'); +const nonexistentFile = fixtures.path('non-existent'); const existingFile = fixtures.path('exit.js'); const existingFile2 = fixtures.path('create-file.js'); const existingDir = fixtures.path('empty'); const existingDir2 = fixtures.path('keys'); const uv = process.binding('uv'); -// ASYNC_CALL - -fs.stat(fn, common.mustCall((err) => { - assert.strictEqual(fn, err.path); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, stat '${fn}'`); - assert.strictEqual(err.errno, uv.UV_ENOENT); - assert.strictEqual(err.code, 'ENOENT'); - assert.strictEqual(err.syscall, 'stat'); -})); - -fs.lstat(fn, common.mustCall((err) => { - assert.strictEqual(fn, err.path); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, lstat '${fn}'`); - assert.strictEqual(err.errno, uv.UV_ENOENT); - assert.strictEqual(err.code, 'ENOENT'); - assert.strictEqual(err.syscall, 'lstat'); -})); +// stat +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, stat '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'stat'); + return true; + } + + fs.stat(nonexistentFile, common.mustCall(validateError)); + + assert.throws( + () => fs.statSync(nonexistentFile), + validateError + ); +} +// lstat { - const fd = fs.openSync(existingFile, 'r'); - fs.closeSync(fd); - fs.fstat(fd, common.mustCall((err) => { + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, lstat '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'lstat'); + return true; + }; + + fs.lstat(nonexistentFile, common.mustCall(validateError)); + assert.throws( + () => fs.lstatSync(nonexistentFile), + validateError + ); +} + +// fstat +{ + const validateError = (err) => { assert.strictEqual(err.message, 'EBADF: bad file descriptor, fstat'); assert.strictEqual(err.errno, uv.UV_EBADF); assert.strictEqual(err.code, 'EBADF'); assert.strictEqual(err.syscall, 'fstat'); - })); -} + return true; + }; -fs.realpath(fn, common.mustCall((err) => { - assert.strictEqual(fn, err.path); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, lstat '${fn}'`); - assert.strictEqual(err.errno, uv.UV_ENOENT); - assert.strictEqual(err.code, 'ENOENT'); - assert.strictEqual(err.syscall, 'lstat'); -})); - -fs.readlink(fn, common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -fs.link(fn, 'foo', common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -fs.link(existingFile, existingFile2, common.mustCall((err) => { - assert.ok(err.message.includes(existingFile)); - assert.ok(err.message.includes(existingFile2)); -})); - -fs.symlink(existingFile, existingFile2, common.mustCall((err) => { - assert.ok(err.message.includes(existingFile)); - assert.ok(err.message.includes(existingFile2)); -})); - -fs.unlink(fn, common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -fs.rename(fn, 'foo', common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -fs.rename(existingDir, existingDir2, common.mustCall((err) => { - assert.ok(err.message.includes(existingDir)); - assert.ok(err.message.includes(existingDir2)); -})); - -fs.rmdir(fn, common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -fs.mkdir(existingFile, 0o666, common.mustCall((err) => { - assert.ok(err.message.includes(existingFile)); -})); - -fs.rmdir(existingFile, common.mustCall((err) => { - assert.ok(err.message.includes(existingFile)); -})); - -fs.chmod(fn, 0o666, common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -fs.open(fn, 'r', 0o666, common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -fs.readFile(fn, common.mustCall((err) => { - assert.ok(err.message.includes(fn)); -})); - -// Sync - -const errors = []; -let expected = 0; - -try { - ++expected; - fs.statSync(fn); -} catch (err) { - errors.push('stat'); - assert.strictEqual(fn, err.path); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, stat '${fn}'`); - assert.strictEqual(err.errno, uv.UV_ENOENT); - assert.strictEqual(err.code, 'ENOENT'); - assert.strictEqual(err.syscall, 'stat'); -} + const fd = fs.openSync(existingFile, 'r'); + fs.closeSync(fd); -try { - ++expected; - fs.mkdirSync(existingFile, 0o666); -} catch (err) { - errors.push('mkdir'); - assert.ok(err.message.includes(existingFile)); -} + fs.fstat(fd, common.mustCall(validateError)); -try { - ++expected; - fs.chmodSync(fn, 0o666); -} catch (err) { - errors.push('chmod'); - assert.ok(err.message.includes(fn)); + assert.throws( + () => fs.fstatSync(fd), + validateError + ); } -try { - ++expected; - fs.lstatSync(fn); -} catch (err) { - errors.push('lstat'); - assert.strictEqual(fn, err.path); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, lstat '${fn}'`); - assert.strictEqual(err.errno, uv.UV_ENOENT); - assert.strictEqual(err.code, 'ENOENT'); - assert.strictEqual(err.syscall, 'lstat'); +// realpath +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, lstat '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'lstat'); + return true; + }; + + fs.realpath(nonexistentFile, common.mustCall(validateError)); + + assert.throws( + () => fs.realpathSync(nonexistentFile), + validateError + ); } -try { - ++expected; - const fd = fs.openSync(existingFile, 'r'); - fs.closeSync(fd); - fs.fstatSync(fd); -} catch (err) { - errors.push('fstat'); - assert.strictEqual(err.message, 'EBADF: bad file descriptor, fstat'); - assert.strictEqual(err.errno, uv.UV_EBADF); - assert.strictEqual(err.code, 'EBADF'); - assert.strictEqual(err.syscall, 'fstat'); +// readlink +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, readlink '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'readlink'); + return true; + }; + + fs.readlink(nonexistentFile, common.mustCall(validateError)); + + assert.throws( + () => fs.readlinkSync(nonexistentFile), + validateError + ); } -try { - ++expected; - fs.realpathSync(fn); -} catch (err) { - errors.push('realpath'); - assert.strictEqual(fn, err.path); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, lstat '${fn}'`); - assert.strictEqual(err.errno, uv.UV_ENOENT); - assert.strictEqual(err.code, 'ENOENT'); - assert.strictEqual(err.syscall, 'lstat'); +// link nonexistent file +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual('foo', err.dest); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, link '${nonexistentFile}' -> 'foo'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'link'); + return true; + }; + + fs.link(nonexistentFile, 'foo', common.mustCall(validateError)); + + assert.throws( + () => fs.linkSync(nonexistentFile, 'foo'), + validateError + ); } -try { - ++expected; - fs.readlinkSync(fn); -} catch (err) { - errors.push('readlink'); - assert.ok(err.message.includes(fn)); +// link existing file +{ + const validateError = (err) => { + assert.strictEqual(existingFile, err.path); + assert.strictEqual(existingFile2, err.dest); + assert.strictEqual( + err.message, + `EEXIST: file already exists, link '${existingFile}' -> ` + + `'${existingFile2}'`); + assert.strictEqual(err.errno, uv.UV_EEXIST); + assert.strictEqual(err.code, 'EEXIST'); + assert.strictEqual(err.syscall, 'link'); + return true; + }; + + fs.link(existingFile, existingFile2, common.mustCall(validateError)); + + assert.throws( + () => fs.linkSync(existingFile, existingFile2), + validateError + ); } -try { - ++expected; - fs.linkSync(fn, 'foo'); -} catch (err) { - errors.push('link'); - assert.ok(err.message.includes(fn)); +// symlink +{ + const validateError = (err) => { + assert.strictEqual(existingFile, err.path); + assert.strictEqual(existingFile2, err.dest); + assert.strictEqual( + err.message, + `EEXIST: file already exists, symlink '${existingFile}' -> ` + + `'${existingFile2}'`); + assert.strictEqual(err.errno, uv.UV_EEXIST); + assert.strictEqual(err.code, 'EEXIST'); + assert.strictEqual(err.syscall, 'symlink'); + return true; + }; + + fs.symlink(existingFile, existingFile2, common.mustCall(validateError)); + + assert.throws( + () => fs.symlinkSync(existingFile, existingFile2), + validateError + ); } -try { - ++expected; - fs.linkSync(existingFile, existingFile2); -} catch (err) { - errors.push('link'); - assert.ok(err.message.includes(existingFile)); - assert.ok(err.message.includes(existingFile2)); +// unlink +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, unlink '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'unlink'); + return true; + }; + + fs.unlink(nonexistentFile, common.mustCall(validateError)); + + assert.throws( + () => fs.unlinkSync(nonexistentFile), + validateError + ); } -try { - ++expected; - fs.symlinkSync(existingFile, existingFile2); -} catch (err) { - errors.push('symlink'); - assert.ok(err.message.includes(existingFile)); - assert.ok(err.message.includes(existingFile2)); +// rename +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual('foo', err.dest); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, rename '${nonexistentFile}' ` + + '-> \'foo\''); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'rename'); + return true; + }; + + fs.rename(nonexistentFile, 'foo', common.mustCall(validateError)); + + assert.throws( + () => fs.renameSync(nonexistentFile, 'foo'), + validateError + ); } -try { - ++expected; - fs.unlinkSync(fn); -} catch (err) { - errors.push('unlink'); - assert.ok(err.message.includes(fn)); +// rename non-empty directory +{ + const validateError = (err) => { + assert.strictEqual(existingDir, err.path); + assert.strictEqual(existingDir2, err.dest); + assert.strictEqual( + err.message, + `ENOTEMPTY: directory not empty, rename '${existingDir}' -> ` + + `'${existingDir2}'`); + assert.strictEqual(err.errno, uv.UV_ENOTEMPTY); + assert.strictEqual(err.code, 'ENOTEMPTY'); + assert.strictEqual(err.syscall, 'rename'); + return true; + }; + + fs.rename(existingDir, existingDir2, common.mustCall(validateError)); + + assert.throws( + () => fs.renameSync(existingDir, existingDir2), + validateError + ); } -try { - ++expected; - fs.rmdirSync(fn); -} catch (err) { - errors.push('rmdir'); - assert.ok(err.message.includes(fn)); +// rmdir +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, rmdir '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'rmdir'); + return true; + }; + + fs.rmdir(nonexistentFile, common.mustCall(validateError)); + + assert.throws( + () => fs.rmdirSync(nonexistentFile), + validateError + ); } -try { - ++expected; - fs.rmdirSync(existingFile); -} catch (err) { - errors.push('rmdir'); - assert.ok(err.message.includes(existingFile)); +// mkdir +{ + const validateError = (err) => { + assert.strictEqual(existingFile, err.path); + assert.strictEqual( + err.message, + `EEXIST: file already exists, mkdir '${existingFile}'`); + assert.strictEqual(err.errno, uv.UV_EEXIST); + assert.strictEqual(err.code, 'EEXIST'); + assert.strictEqual(err.syscall, 'mkdir'); + return true; + }; + + fs.mkdir(existingFile, 0o666, common.mustCall(validateError)); + + assert.throws( + () => fs.mkdirSync(existingFile, 0o666), + validateError + ); } -try { - ++expected; - fs.openSync(fn, 'r'); -} catch (err) { - errors.push('opens'); - assert.ok(err.message.includes(fn)); +// rmdir +{ + const validateError = (err) => { + assert.strictEqual(existingFile, err.path); + assert.strictEqual( + err.message, + `ENOTDIR: not a directory, rmdir '${existingFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOTDIR); + assert.strictEqual(err.code, 'ENOTDIR'); + assert.strictEqual(err.syscall, 'rmdir'); + return true; + }; + + fs.rmdir(existingFile, common.mustCall(validateError)); + + assert.throws( + () => fs.rmdirSync(existingFile), + validateError + ); } -try { - ++expected; - fs.renameSync(fn, 'foo'); -} catch (err) { - errors.push('rename'); - assert.ok(err.message.includes(fn)); +// chmod +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, chmod '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'chmod'); + return true; + }; + + fs.chmod(nonexistentFile, 0o666, common.mustCall(validateError)); + + assert.throws( + () => fs.chmodSync(nonexistentFile, 0o666), + validateError + ); } -try { - ++expected; - fs.renameSync(existingDir, existingDir2); -} catch (err) { - errors.push('rename'); - assert.ok(err.message.includes(existingDir)); - assert.ok(err.message.includes(existingDir2)); +// open +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, open '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'open'); + return true; + }; + + fs.open(nonexistentFile, 'r', 0o666, common.mustCall(validateError)); + + assert.throws( + () => fs.openSync(nonexistentFile, 'r', 0o666), + validateError + ); } -try { - ++expected; - fs.readdirSync(fn); -} catch (err) { - errors.push('readdir'); - assert.ok(err.message.includes(fn)); +// read +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, open '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'open'); + return true; + }; + + fs.readFile(nonexistentFile, common.mustCall(validateError)); + + assert.throws( + () => fs.readFileSync(nonexistentFile), + validateError + ); } -assert.strictEqual(expected, errors.length); +// readdir +{ + const validateError = (err) => { + assert.strictEqual(nonexistentFile, err.path); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, scandir '${nonexistentFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'scandir'); + return true; + }; + + fs.readdir(nonexistentFile, common.mustCall(validateError)); + + assert.throws( + () => fs.readdirSync(nonexistentFile), + validateError + ); +} From 5c90a0f3096a495a35ba95a8165b15a5f203b581 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sun, 21 Jan 2018 16:47:05 +0800 Subject: [PATCH 2/4] [squash] fix platform-dependent errors --- test/parallel/test-fs-error-messages.js | 36 +++++++++++++++++-------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index 8c7bf682b74b56..822a8cff781ba1 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -42,10 +42,10 @@ const uv = process.binding('uv'); assert.strictEqual(err.code, 'ENOENT'); assert.strictEqual(err.syscall, 'stat'); return true; - } - + }; + fs.stat(nonexistentFile, common.mustCall(validateError)); - + assert.throws( () => fs.statSync(nonexistentFile), validateError @@ -139,7 +139,9 @@ const uv = process.binding('uv'); { const validateError = (err) => { assert.strictEqual(nonexistentFile, err.path); - assert.strictEqual('foo', err.dest); + // Could be resolved to an absolute path + assert.ok(err.dest.endsWith('foo'), + `expect ${err.dest} to ends with 'foo'`); assert.strictEqual( err.message, `ENOENT: no such file or directory, link '${nonexistentFile}' -> 'foo'`); @@ -228,7 +230,9 @@ const uv = process.binding('uv'); { const validateError = (err) => { assert.strictEqual(nonexistentFile, err.path); - assert.strictEqual('foo', err.dest); + // Could be resolved to an absolute path + assert.ok(err.dest.endsWith('foo'), + `expect ${err.dest} to ends with 'foo'`); assert.strictEqual( err.message, `ENOENT: no such file or directory, rename '${nonexistentFile}' ` + @@ -252,13 +256,23 @@ const uv = process.binding('uv'); const validateError = (err) => { assert.strictEqual(existingDir, err.path); assert.strictEqual(existingDir2, err.dest); - assert.strictEqual( - err.message, - `ENOTEMPTY: directory not empty, rename '${existingDir}' -> ` + - `'${existingDir2}'`); - assert.strictEqual(err.errno, uv.UV_ENOTEMPTY); - assert.strictEqual(err.code, 'ENOTEMPTY'); assert.strictEqual(err.syscall, 'rename'); + // Could be ENOTEMPTY or EEXIST, depending on the platform + if (err.code === 'ENOTEMPTY') { + assert.strictEqual( + err.message, + `ENOTEMPTY: directory not empty, rename '${existingDir}' -> ` + + `'${existingDir2}'`); + assert.strictEqual(err.errno, uv.UV_ENOTEMPTY); + assert.strictEqual(err.code, 'ENOTEMPTY'); + } else { + assert.strictEqual( + err.message, + `EEXIST: file already exists, rename '${existingDir}' -> ` + + `'${existingDir2}'`); + assert.strictEqual(err.errno, uv.UV_EEXIST); + assert.strictEqual(err.code, 'EEXIST'); + } return true; }; From 15061d2f020529560a04727600f2a851e903a6b8 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 22 Jan 2018 14:25:32 +0800 Subject: [PATCH 3/4] [squash] fix error message on windows, improve comments --- test/parallel/test-fs-error-messages.js | 74 +++++++++++++++---------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index 822a8cff781ba1..e469819c5dc6a6 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -31,6 +31,18 @@ const existingDir = fixtures.path('empty'); const existingDir2 = fixtures.path('keys'); const uv = process.binding('uv'); +// Template tag function for escaping special characters in strings so that: +// new RegExp(re`${str}`).test(str) === true +function re(literals, ...values) { + const escapeRE = /[\\^$.*+?()[\]{}|=!<>:-]/g; + let result = literals[0].replace(escapeRE, '\\$&'); + for (const [i, value] of values.entries()) { + result += value.replace(escapeRE, '\\$&'); + result += literals[i + 1].replace(escapeRE, '\\$&'); + } + return result; +} + // stat { const validateError = (err) => { @@ -141,10 +153,11 @@ const uv = process.binding('uv'); assert.strictEqual(nonexistentFile, err.path); // Could be resolved to an absolute path assert.ok(err.dest.endsWith('foo'), - `expect ${err.dest} to ends with 'foo'`); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, link '${nonexistentFile}' -> 'foo'`); + `expect ${err.dest} to end with 'foo'`); + const regexp = new RegExp('^ENOENT: no such file or directory, link ' + + re`'${nonexistentFile}' -> ` + '\'.*foo\''); + assert.ok(regexp.test(err.message), + `Expect ${err.message} to match ${regexp}`); assert.strictEqual(err.errno, uv.UV_ENOENT); assert.strictEqual(err.code, 'ENOENT'); assert.strictEqual(err.syscall, 'link'); @@ -232,11 +245,11 @@ const uv = process.binding('uv'); assert.strictEqual(nonexistentFile, err.path); // Could be resolved to an absolute path assert.ok(err.dest.endsWith('foo'), - `expect ${err.dest} to ends with 'foo'`); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, rename '${nonexistentFile}' ` + - '-> \'foo\''); + `expect ${err.dest} to end with 'foo'`); + const regexp = new RegExp('ENOENT: no such file or directory, rename ' + + re`'${nonexistentFile}' -> ` + '\'.*foo\''); + assert.ok(regexp.test(err.message), + `Expect ${err.message} to match ${regexp}`); assert.strictEqual(err.errno, uv.UV_ENOENT); assert.strictEqual(err.code, 'ENOENT'); assert.strictEqual(err.syscall, 'rename'); @@ -257,21 +270,26 @@ const uv = process.binding('uv'); assert.strictEqual(existingDir, err.path); assert.strictEqual(existingDir2, err.dest); assert.strictEqual(err.syscall, 'rename'); - // Could be ENOTEMPTY or EEXIST, depending on the platform + // Could be ENOTEMPTY, EEXIST, or EPERM, depending on the platform if (err.code === 'ENOTEMPTY') { assert.strictEqual( err.message, `ENOTEMPTY: directory not empty, rename '${existingDir}' -> ` + `'${existingDir2}'`); assert.strictEqual(err.errno, uv.UV_ENOTEMPTY); - assert.strictEqual(err.code, 'ENOTEMPTY'); - } else { + } else if (err.code === 'EEXIST') { // smartos and aix assert.strictEqual( err.message, `EEXIST: file already exists, rename '${existingDir}' -> ` + `'${existingDir2}'`); assert.strictEqual(err.errno, uv.UV_EEXIST); - assert.strictEqual(err.code, 'EEXIST'); + } else { // windows + assert.strictEqual( + err.message, + `EPERM: operation not permitted, rename '${existingDir}' -> ` + + `'${existingDir2}'`); + assert.strictEqual(err.errno, uv.UV_EPERM); + assert.strictEqual(err.code, 'EPERM'); } return true; }; @@ -305,44 +323,44 @@ const uv = process.binding('uv'); ); } -// mkdir +// rmdir a file { const validateError = (err) => { assert.strictEqual(existingFile, err.path); assert.strictEqual( err.message, - `EEXIST: file already exists, mkdir '${existingFile}'`); - assert.strictEqual(err.errno, uv.UV_EEXIST); - assert.strictEqual(err.code, 'EEXIST'); - assert.strictEqual(err.syscall, 'mkdir'); + `ENOTDIR: not a directory, rmdir '${existingFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOTDIR); + assert.strictEqual(err.code, 'ENOTDIR'); + assert.strictEqual(err.syscall, 'rmdir'); return true; }; - fs.mkdir(existingFile, 0o666, common.mustCall(validateError)); + fs.rmdir(existingFile, common.mustCall(validateError)); assert.throws( - () => fs.mkdirSync(existingFile, 0o666), + () => fs.rmdirSync(existingFile), validateError ); } -// rmdir +// mkdir { const validateError = (err) => { assert.strictEqual(existingFile, err.path); assert.strictEqual( err.message, - `ENOTDIR: not a directory, rmdir '${existingFile}'`); - assert.strictEqual(err.errno, uv.UV_ENOTDIR); - assert.strictEqual(err.code, 'ENOTDIR'); - assert.strictEqual(err.syscall, 'rmdir'); + `EEXIST: file already exists, mkdir '${existingFile}'`); + assert.strictEqual(err.errno, uv.UV_EEXIST); + assert.strictEqual(err.code, 'EEXIST'); + assert.strictEqual(err.syscall, 'mkdir'); return true; }; - fs.rmdir(existingFile, common.mustCall(validateError)); + fs.mkdir(existingFile, 0o666, common.mustCall(validateError)); assert.throws( - () => fs.rmdirSync(existingFile), + () => fs.mkdirSync(existingFile, 0o666), validateError ); } @@ -389,7 +407,7 @@ const uv = process.binding('uv'); ); } -// read +// readFile { const validateError = (err) => { assert.strictEqual(nonexistentFile, err.path); From 9da5b0e0898d4fe80b5074a0c7c36eaceeb5a5ae Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 22 Jan 2018 19:16:56 +0800 Subject: [PATCH 4/4] more windows fixes --- test/parallel/test-fs-error-messages.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index e469819c5dc6a6..ef38652d7a3df0 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -327,12 +327,19 @@ function re(literals, ...values) { { const validateError = (err) => { assert.strictEqual(existingFile, err.path); - assert.strictEqual( - err.message, - `ENOTDIR: not a directory, rmdir '${existingFile}'`); - assert.strictEqual(err.errno, uv.UV_ENOTDIR); - assert.strictEqual(err.code, 'ENOTDIR'); assert.strictEqual(err.syscall, 'rmdir'); + if (err.code === 'ENOTDIR') { + assert.strictEqual( + err.message, + `ENOTDIR: not a directory, rmdir '${existingFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOTDIR); + } else { // windows + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, rmdir '${existingFile}'`); + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + } return true; };