1'use strict'; 2const common = require('../common'); 3 4const assert = require('assert'); 5const fs = require('fs'); 6const path = require('path'); 7 8const tmpdir = require('../common/tmpdir'); 9 10// Basic usage tests. 11assert.throws( 12 () => { 13 fs.watchFile('./some-file'); 14 }, 15 { 16 code: 'ERR_INVALID_ARG_TYPE', 17 name: 'TypeError' 18 }); 19 20assert.throws( 21 () => { 22 fs.watchFile('./another-file', {}, 'bad listener'); 23 }, 24 { 25 code: 'ERR_INVALID_ARG_TYPE', 26 name: 'TypeError' 27 }); 28 29assert.throws(() => { 30 fs.watchFile(new Object(), common.mustNotCall()); 31}, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); 32 33const enoentFile = path.join(tmpdir.path, 'non-existent-file'); 34const expectedStatObject = new fs.Stats( 35 0, // dev 36 0, // mode 37 0, // nlink 38 0, // uid 39 0, // gid 40 0, // rdev 41 0, // blksize 42 0, // ino 43 0, // size 44 0, // blocks 45 Date.UTC(1970, 0, 1, 0, 0, 0), // atime 46 Date.UTC(1970, 0, 1, 0, 0, 0), // mtime 47 Date.UTC(1970, 0, 1, 0, 0, 0), // ctime 48 Date.UTC(1970, 0, 1, 0, 0, 0) // birthtime 49); 50 51tmpdir.refresh(); 52 53// If the file initially didn't exist, and gets created at a later point of 54// time, the callback should be invoked again with proper values in stat object 55let fileExists = false; 56 57const watcher = 58 fs.watchFile(enoentFile, { interval: 0 }, common.mustCall((curr, prev) => { 59 if (!fileExists) { 60 // If the file does not exist, all the fields should be zero and the date 61 // fields should be UNIX EPOCH time 62 assert.deepStrictEqual(curr, expectedStatObject); 63 assert.deepStrictEqual(prev, expectedStatObject); 64 // Create the file now, so that the callback will be called back once the 65 // event loop notices it. 66 fs.closeSync(fs.openSync(enoentFile, 'w')); 67 fileExists = true; 68 } else { 69 // If the ino (inode) value is greater than zero, it means that the file 70 // is present in the filesystem and it has a valid inode number. 71 assert(curr.ino > 0); 72 // As the file just got created, previous ino value should be lesser than 73 // or equal to zero (non-existent file). 74 assert(prev.ino <= 0); 75 // Stop watching the file 76 fs.unwatchFile(enoentFile); 77 watcher.stop(); // Stopping a stopped watcher should be a noop 78 } 79 }, 2)); 80 81// 'stop' should only be emitted once - stopping a stopped watcher should 82// not trigger a 'stop' event. 83watcher.on('stop', common.mustCall()); 84 85// Watch events should callback with a filename on supported systems. 86// Omitting AIX. It works but not reliably. 87if (common.isLinux || common.isOSX || common.isWindows) { 88 const dir = path.join(tmpdir.path, 'watch'); 89 90 fs.mkdir(dir, common.mustCall(function(err) { 91 if (err) assert.fail(err); 92 93 fs.watch(dir, common.mustCall(function(eventType, filename) { 94 clearInterval(interval); 95 this._handle.close(); 96 assert.strictEqual(filename, 'foo.txt'); 97 })); 98 99 const interval = setInterval(() => { 100 fs.writeFile(path.join(dir, 'foo.txt'), 'foo', common.mustCall((err) => { 101 if (err) assert.fail(err); 102 })); 103 }, 1); 104 })); 105} 106