diff options
author | cjihrig <cjihrig@gmail.com> | 2019-08-16 13:17:21 -0400 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-08-23 13:59:07 -0700 |
commit | 53816cce699d02fb28a49b258e1fbc474568bbf8 (patch) | |
tree | b022ff51ac6aa0b0a55cc1a34241eb118d5c0f3a /test | |
parent | 2b1bcba385af380e3eaffd44315c83d3c0201cfe (diff) | |
download | android-node-v8-53816cce699d02fb28a49b258e1fbc474568bbf8.tar.gz android-node-v8-53816cce699d02fb28a49b258e1fbc474568bbf8.tar.bz2 android-node-v8-53816cce699d02fb28a49b258e1fbc474568bbf8.zip |
fs: add recursive option to rmdir()
This commit adds a recursive option to fs.rmdir(),
fs.rmdirSync(), and fs.promises.rmdir(). The implementation
is a port of the npm module rimraf.
PR-URL: https://github.com/nodejs/node/pull/29168
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Ben Coe <bencoe@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/parallel/test-fs-rmdir-recursive.js | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/test/parallel/test-fs-rmdir-recursive.js b/test/parallel/test-fs-rmdir-recursive.js new file mode 100644 index 0000000000..b020221b27 --- /dev/null +++ b/test/parallel/test-fs-rmdir-recursive.js @@ -0,0 +1,152 @@ +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const { validateRmdirOptions } = require('internal/fs/utils'); +let count = 0; + +tmpdir.refresh(); + +function makeNonEmptyDirectory() { + const dirname = `rmdir-recursive-${count}`; + fs.mkdirSync(path.join(dirname, 'foo', 'bar', 'baz'), { recursive: true }); + fs.writeFileSync(path.join(dirname, 'text.txt'), 'hello', 'utf8'); + count++; + return dirname; +} + +// Test the asynchronous version. +{ + const dir = makeNonEmptyDirectory(); + + // Removal should fail without the recursive option. + fs.rmdir(dir, common.mustCall((err) => { + assert.strictEqual(err.syscall, 'rmdir'); + + // Removal should fail without the recursive option set to true. + fs.rmdir(dir, { recursive: false }, common.mustCall((err) => { + assert.strictEqual(err.syscall, 'rmdir'); + + // Recursive removal should succeed. + fs.rmdir(dir, { recursive: true }, common.mustCall((err) => { + assert.ifError(err); + + // No error should occur if recursive and the directory does not exist. + fs.rmdir(dir, { recursive: true }, common.mustCall((err) => { + assert.ifError(err); + + // Attempted removal should fail now because the directory is gone. + fs.rmdir(dir, common.mustCall((err) => { + assert.strictEqual(err.syscall, 'rmdir'); + })); + })); + })); + })); + })); +} + +// Test the synchronous version. +{ + const dir = makeNonEmptyDirectory(); + + // Removal should fail without the recursive option set to true. + common.expectsError(() => { + fs.rmdirSync(dir); + }, { syscall: 'rmdir' }); + common.expectsError(() => { + fs.rmdirSync(dir, { recursive: false }); + }, { syscall: 'rmdir' }); + + // Recursive removal should succeed. + fs.rmdirSync(dir, { recursive: true }); + + // No error should occur if recursive and the directory does not exist. + fs.rmdirSync(dir, { recursive: true }); + + // Attempted removal should fail now because the directory is gone. + common.expectsError(() => fs.rmdirSync(dir), { syscall: 'rmdir' }); +} + +// Test the Promises based version. +(async () => { + const dir = makeNonEmptyDirectory(); + + // Removal should fail without the recursive option set to true. + assert.rejects(fs.promises.rmdir(dir), { syscall: 'rmdir' }); + assert.rejects(fs.promises.rmdir(dir, { recursive: false }), { + syscall: 'rmdir' + }); + + // Recursive removal should succeed. + await fs.promises.rmdir(dir, { recursive: true }); + + // No error should occur if recursive and the directory does not exist. + await fs.promises.rmdir(dir, { recursive: true }); + + // Attempted removal should fail now because the directory is gone. + assert.rejects(fs.promises.rmdir(dir), { syscall: 'rmdir' }); +})(); + +// Test input validation. +{ + const defaults = { + emfileWait: 1000, + maxBusyTries: 3, + recursive: false + }; + const modified = { + emfileWait: 953, + maxBusyTries: 5, + recursive: true + }; + + assert.deepStrictEqual(validateRmdirOptions(), defaults); + assert.deepStrictEqual(validateRmdirOptions({}), defaults); + assert.deepStrictEqual(validateRmdirOptions(modified), modified); + assert.deepStrictEqual(validateRmdirOptions({ + maxBusyTries: 99 + }), { + emfileWait: 1000, + maxBusyTries: 99, + recursive: false + }); + + [null, 'foo', 5, NaN].forEach((bad) => { + common.expectsError(() => { + validateRmdirOptions(bad); + }, { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: /^The "options" argument must be of type object\./ + }); + }); + + [undefined, null, 'foo', Infinity, function() {}].forEach((bad) => { + common.expectsError(() => { + validateRmdirOptions({ recursive: bad }); + }, { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: /^The "recursive" argument must be of type boolean\./ + }); + }); + + common.expectsError(() => { + validateRmdirOptions({ emfileWait: -1 }); + }, { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: /^The value of "emfileWait" is out of range\./ + }); + + common.expectsError(() => { + validateRmdirOptions({ maxBusyTries: -1 }); + }, { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: /^The value of "maxBusyTries" is out of range\./ + }); +} |