1 var path = require('path')
3 var test = require('tap').test
5 var readdir = require('graceful-fs').readdir
6 var readdirSync = require('graceful-fs').readdirSync
7 var statSync = require('graceful-fs').statSync
8 var writeFile = require('graceful-fs').writeFile
9 var mkdirp = require('mkdirp')
10 var mkdtemp = require('tmp').dir
11 var tmpFile = require('tmp').file
13 var requireInject = require('require-inject')
14 var vacuum = requireInject('../vacuum.js', {
16 'lstat': require('graceful-fs').lstat,
17 'readdir': function (dir, cb) {
18 readdir(dir, function (err, files) {
19 // Simulate racy removal by creating a file after vacuum
20 // thinks the directory is empty
21 if (dir === partialPath && files.length === 0) {
22 tmpFile({dir: dir}, function (err, path, fd) {
31 'rmdir': require('graceful-fs').rmdir,
32 'unlink': require('graceful-fs').unlink
41 var SHORT_PATH = path.join('i', 'am', 'a', 'path')
42 var PARTIAL_PATH = path.join(SHORT_PATH, 'that', 'ends', 'at', 'a')
43 var FULL_PATH = path.join(PARTIAL_PATH, 'file')
46 function log () { messages.push(Array.prototype.slice.call(arguments).join(' ')) }
48 var testBase, partialPath, fullPath
49 test('xXx setup xXx', function (t) {
50 mkdtemp(TEMP_OPTIONS, function (er, tmpdir) {
51 t.ifError(er, 'temp directory exists')
53 testBase = path.resolve(tmpdir, SHORT_PATH)
54 partialPath = path.resolve(tmpdir, PARTIAL_PATH)
55 fullPath = path.resolve(tmpdir, FULL_PATH)
57 mkdirp(partialPath, function (er) {
58 t.ifError(er, 'made test path')
60 writeFile(fullPath, new Buffer('hi'), function (er) {
61 t.ifError(er, 'made file')
69 test('racy removal should quit gracefully', function (t) {
70 vacuum(fullPath, {purge: false, base: testBase, log: log}, function (er) {
71 t.ifError(er, 'cleaned up to base')
73 t.equal(messages.length, 3, 'got 2 removal & 1 quit message')
74 t.equal(messages[2], 'quitting because new (racy) entries in ' + partialPath)
77 var verifyPath = fullPath
79 function verify () { stat = statSync(verifyPath) }
81 // handle the file separately
82 t.throws(verify, verifyPath + ' cannot be statted')
83 t.notOk(stat && stat.isFile(), verifyPath + ' is totally gone')
84 verifyPath = path.dirname(verifyPath)
86 for (var i = 0; i < 4; i++) {
87 t.doesNotThrow(function () {
88 stat = statSync(verifyPath)
89 }, verifyPath + ' can be statted')
90 t.ok(stat && stat.isDirectory(), verifyPath + ' is still a directory')
91 verifyPath = path.dirname(verifyPath)
94 t.doesNotThrow(function () {
95 stat = statSync(testBase)
96 }, testBase + ' can be statted')
97 t.ok(stat && stat.isDirectory(), testBase + ' is still a directory')
99 var files = readdirSync(testBase)
100 t.equal(files.length, 1, 'base directory untouched')