1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24if (common.isIBMi) 25 common.skip('IBMi does not support fs.watch()'); 26 27const assert = require('assert'); 28const fs = require('fs'); 29const path = require('path'); 30 31const tmpdir = require('../common/tmpdir'); 32 33if (!common.isMainThread) 34 common.skip('process.chdir is not available in Workers'); 35 36const expectFilePath = common.isWindows || 37 common.isLinux || 38 common.isOSX || 39 common.isAIX; 40 41const testDir = tmpdir.path; 42 43tmpdir.refresh(); 44 45{ 46 const filepath = path.join(testDir, 'watch.txt'); 47 48 fs.writeFileSync(filepath, 'hello'); 49 50 const watcher = fs.watch(filepath); 51 watcher.on('change', common.mustCall(function(event, filename) { 52 assert.strictEqual(event, 'change'); 53 54 if (expectFilePath) { 55 assert.strictEqual(filename, 'watch.txt'); 56 } 57 watcher.close(); 58 })); 59 60 setImmediate(function() { 61 fs.writeFileSync(filepath, 'world'); 62 }); 63} 64 65{ 66 const filepathAbs = path.join(testDir, 'hasOwnProperty'); 67 68 process.chdir(testDir); 69 70 fs.writeFileSync(filepathAbs, 'howdy'); 71 72 const watcher = 73 fs.watch('hasOwnProperty', common.mustCall(function(event, filename) { 74 assert.strictEqual(event, 'change'); 75 76 if (expectFilePath) { 77 assert.strictEqual(filename, 'hasOwnProperty'); 78 } 79 watcher.close(); 80 })); 81 82 setImmediate(function() { 83 fs.writeFileSync(filepathAbs, 'pardner'); 84 }); 85} 86 87{ 88 const testsubdir = fs.mkdtempSync(testDir + path.sep); 89 const filepath = path.join(testsubdir, 'newfile.txt'); 90 91 const watcher = 92 fs.watch(testsubdir, common.mustCall(function(event, filename) { 93 const renameEv = common.isSunOS || common.isAIX ? 'change' : 'rename'; 94 assert.strictEqual(event, renameEv); 95 if (expectFilePath) { 96 assert.strictEqual(filename, 'newfile.txt'); 97 } else { 98 assert.strictEqual(filename, null); 99 } 100 watcher.close(); 101 })); 102 103 setImmediate(function() { 104 const fd = fs.openSync(filepath, 'w'); 105 fs.closeSync(fd); 106 }); 107 108} 109 110// https://github.com/joyent/node/issues/2293 - non-persistent watcher should 111// not block the event loop 112{ 113 fs.watch(__filename, { persistent: false }, common.mustNotCall()); 114} 115 116// Whitebox test to ensure that wrapped FSEvent is safe 117// https://github.com/joyent/node/issues/6690 118{ 119 let oldhandle; 120 common.expectsInternalAssertion( 121 () => { 122 const w = fs.watch(__filename, common.mustNotCall()); 123 oldhandle = w._handle; 124 w._handle = { close: w._handle.close }; 125 w.close(); 126 }, 127 'handle must be a FSEvent' 128 ); 129 oldhandle.close(); // clean up 130} 131