11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// Flags: --expose-internals
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst assert = require('assert');
81cb0ef41Sopenharmony_ciconst { BigIntStats } = require('internal/fs/utils');
91cb0ef41Sopenharmony_ciconst fs = require('fs');
101cb0ef41Sopenharmony_ciconst path = require('path');
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir');
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst enoentFile = path.join(tmpdir.path, 'non-existent-file');
151cb0ef41Sopenharmony_ciconst expectedStatObject = new BigIntStats(
161cb0ef41Sopenharmony_ci  0n,                                        // dev
171cb0ef41Sopenharmony_ci  0n,                                        // mode
181cb0ef41Sopenharmony_ci  0n,                                        // nlink
191cb0ef41Sopenharmony_ci  0n,                                        // uid
201cb0ef41Sopenharmony_ci  0n,                                        // gid
211cb0ef41Sopenharmony_ci  0n,                                        // rdev
221cb0ef41Sopenharmony_ci  0n,                                        // blksize
231cb0ef41Sopenharmony_ci  0n,                                        // ino
241cb0ef41Sopenharmony_ci  0n,                                        // size
251cb0ef41Sopenharmony_ci  0n,                                        // blocks
261cb0ef41Sopenharmony_ci  0n,                                        // atimeMs
271cb0ef41Sopenharmony_ci  0n,                                        // mtimeMs
281cb0ef41Sopenharmony_ci  0n,                                        // ctimeMs
291cb0ef41Sopenharmony_ci  0n,                                        // birthtimeMs
301cb0ef41Sopenharmony_ci  0n,                                        // atimeNs
311cb0ef41Sopenharmony_ci  0n,                                        // mtimeNs
321cb0ef41Sopenharmony_ci  0n,                                        // ctimeNs
331cb0ef41Sopenharmony_ci  0n                                         // birthtimeNs
341cb0ef41Sopenharmony_ci);
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_citmpdir.refresh();
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci// If the file initially didn't exist, and gets created at a later point of
391cb0ef41Sopenharmony_ci// time, the callback should be invoked again with proper values in stat object
401cb0ef41Sopenharmony_cilet fileExists = false;
411cb0ef41Sopenharmony_ciconst options = { interval: 0, bigint: true };
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ciconst watcher =
441cb0ef41Sopenharmony_ci  fs.watchFile(enoentFile, options, common.mustCall((curr, prev) => {
451cb0ef41Sopenharmony_ci    if (!fileExists) {
461cb0ef41Sopenharmony_ci      // If the file does not exist, all the fields should be zero and the date
471cb0ef41Sopenharmony_ci      // fields should be UNIX EPOCH time
481cb0ef41Sopenharmony_ci      assert.deepStrictEqual(curr, expectedStatObject);
491cb0ef41Sopenharmony_ci      assert.deepStrictEqual(prev, expectedStatObject);
501cb0ef41Sopenharmony_ci      // Create the file now, so that the callback will be called back once the
511cb0ef41Sopenharmony_ci      // event loop notices it.
521cb0ef41Sopenharmony_ci      fs.closeSync(fs.openSync(enoentFile, 'w'));
531cb0ef41Sopenharmony_ci      fileExists = true;
541cb0ef41Sopenharmony_ci    } else {
551cb0ef41Sopenharmony_ci      // If the ino (inode) value is greater than zero, it means that the file
561cb0ef41Sopenharmony_ci      // is present in the filesystem and it has a valid inode number.
571cb0ef41Sopenharmony_ci      assert(curr.ino > 0n);
581cb0ef41Sopenharmony_ci      // As the file just got created, previous ino value should be lesser than
591cb0ef41Sopenharmony_ci      // or equal to zero (non-existent file).
601cb0ef41Sopenharmony_ci      assert(prev.ino <= 0n);
611cb0ef41Sopenharmony_ci      // Stop watching the file
621cb0ef41Sopenharmony_ci      fs.unwatchFile(enoentFile);
631cb0ef41Sopenharmony_ci      watcher.stop();  // Stopping a stopped watcher should be a noop
641cb0ef41Sopenharmony_ci    }
651cb0ef41Sopenharmony_ci  }, 2));
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci// 'stop' should only be emitted once - stopping a stopped watcher should
681cb0ef41Sopenharmony_ci// not trigger a 'stop' event.
691cb0ef41Sopenharmony_ciwatcher.on('stop', common.mustCall());
70