summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/api/fs.md71
-rw-r--r--lib/internal/fs/utils.js163
-rw-r--r--src/env.h26
-rw-r--r--src/node_file.cc11
-rw-r--r--src/node_file.h95
-rw-r--r--test/parallel/test-fs-stat-bigint.js20
-rw-r--r--test/parallel/test-fs-watchfile-bigint.js18
7 files changed, 275 insertions, 129 deletions
diff --git a/doc/api/fs.md b/doc/api/fs.md
index f1b7e1ccbb..1c3742903a 100644
--- a/doc/api/fs.md
+++ b/doc/api/fs.md
@@ -512,7 +512,8 @@ A `fs.Stats` object provides information about a file.
Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and
their synchronous counterparts are of this type.
If `bigint` in the `options` passed to those methods is true, the numeric values
-will be `bigint` instead of `number`.
+will be `bigint` instead of `number`, and the object will contain additional
+nanosecond-precision properties suffixed with `Ns`.
```console
Stats {
@@ -539,7 +540,7 @@ Stats {
`bigint` version:
```console
-Stats {
+BigIntStats {
dev: 2114n,
ino: 48064969n,
mode: 33188n,
@@ -554,6 +555,10 @@ Stats {
mtimeMs: 1318289051000n,
ctimeMs: 1318289051000n,
birthtimeMs: 1318289051000n,
+ atimeNs: 1318289051000000000n,
+ mtimeNs: 1318289051000000000n,
+ ctimeNs: 1318289051000000000n,
+ birthtimeNs: 1318289051000000000n,
atime: Mon, 10 Oct 2011 23:24:11 GMT,
mtime: Mon, 10 Oct 2011 23:24:11 GMT,
ctime: Mon, 10 Oct 2011 23:24:11 GMT,
@@ -726,6 +731,54 @@ added: v8.1.0
The timestamp indicating the creation time of this file expressed in
milliseconds since the POSIX Epoch.
+### stats.atimeNs
+<!-- YAML
+added: REPLACEME
+-->
+
+* {bigint}
+
+Only present when `bigint: true` is passed into the method that generates
+the object.
+The timestamp indicating the last time this file was accessed expressed in
+nanoseconds since the POSIX Epoch.
+
+### stats.mtimeNs
+<!-- YAML
+added: REPLACEME
+-->
+
+* {bigint}
+
+Only present when `bigint: true` is passed into the method that generates
+the object.
+The timestamp indicating the last time this file was modified expressed in
+nanoseconds since the POSIX Epoch.
+
+### stats.ctimeNs
+<!-- YAML
+added: REPLACEME
+-->
+
+* {bigint}
+
+Only present when `bigint: true` is passed into the method that generates
+the object.
+The timestamp indicating the last time the file status was changed expressed
+in nanoseconds since the POSIX Epoch.
+
+### stats.birthtimeNs
+<!-- YAML
+added: REPLACEME
+-->
+
+* {bigint}
+
+Only present when `bigint: true` is passed into the method that generates
+the object.
+The timestamp indicating the creation time of this file expressed in
+nanoseconds since the POSIX Epoch.
+
### stats.atime
<!-- YAML
added: v0.11.13
@@ -765,8 +818,17 @@ The timestamp indicating the creation time of this file.
### Stat Time Values
The `atimeMs`, `mtimeMs`, `ctimeMs`, `birthtimeMs` properties are
-[numbers][MDN-Number] that hold the corresponding times in milliseconds. Their
-precision is platform specific. `atime`, `mtime`, `ctime`, and `birthtime` are
+numeric values that hold the corresponding times in milliseconds. Their
+precision is platform specific. When `bigint: true` is passed into the
+method that generates the object, the properties will be [bigints][],
+otherwise they will be [numbers][MDN-Number].
+
+The `atimeNs`, `mtimeNs`, `ctimeNs`, `birthtimeNs` properties are
+[bigints][] that hold the corresponding times in nanoseconds. They are
+only present when `bigint: true` is passed into the method that generates
+the object. Their precision is platform specific.
+
+`atime`, `mtime`, `ctime`, and `birthtime` are
[`Date`][MDN-Date] object alternate representations of the various times. The
`Date` and number values are not connected. Assigning a new number value, or
mutating the `Date` value, will not be reflected in the corresponding alternate
@@ -4976,6 +5038,7 @@ the file contents.
[`net.Socket`]: net.html#net_class_net_socket
[`stat()`]: fs.html#fs_fs_stat_path_options_callback
[`util.promisify()`]: util.html#util_util_promisify_original
+[bigints]: https://tc39.github.io/proposal-bigint
[Caveats]: #fs_caveats
[Common System Errors]: errors.html#errors_common_system_errors
[FS Constants]: #fs_fs_constants_1
diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js
index 14abad81ec..6cd6f7aceb 100644
--- a/lib/internal/fs/utils.js
+++ b/lib/internal/fs/utils.js
@@ -1,6 +1,6 @@
'use strict';
-const { Reflect } = primordials;
+const { Object, Reflect } = primordials;
const { Buffer, kMaxLength } = require('buffer');
const {
@@ -16,7 +16,8 @@ const {
} = require('internal/errors');
const {
isUint8Array,
- isDate
+ isDate,
+ isBigUint64Array
} = require('internal/util/types');
const { once } = require('internal/util');
const { toPathIfFileURL } = require('internal/url');
@@ -230,27 +231,9 @@ function preprocessSymlinkDestination(path, type, linkPath) {
}
}
-function dateFromNumeric(num) {
- return new Date(Number(num) + 0.5);
-}
-
// Constructor for file stats.
-function Stats(
- dev,
- mode,
- nlink,
- uid,
- gid,
- rdev,
- blksize,
- ino,
- size,
- blocks,
- atim_msec,
- mtim_msec,
- ctim_msec,
- birthtim_msec
-) {
+function StatsBase(dev, mode, nlink, uid, gid, rdev, blksize,
+ ino, size, blocks) {
this.dev = dev;
this.mode = mode;
this.nlink = nlink;
@@ -261,63 +244,132 @@ function Stats(
this.ino = ino;
this.size = size;
this.blocks = blocks;
- this.atimeMs = atim_msec;
- this.mtimeMs = mtim_msec;
- this.ctimeMs = ctim_msec;
- this.birthtimeMs = birthtim_msec;
- this.atime = dateFromNumeric(atim_msec);
- this.mtime = dateFromNumeric(mtim_msec);
- this.ctime = dateFromNumeric(ctim_msec);
- this.birthtime = dateFromNumeric(birthtim_msec);
}
-Stats.prototype._checkModeProperty = function(property) {
- if (isWindows && (property === S_IFIFO || property === S_IFBLK ||
- property === S_IFSOCK)) {
- return false; // Some types are not available on Windows
- }
- if (typeof this.mode === 'bigint') { // eslint-disable-line valid-typeof
- return (this.mode & BigInt(S_IFMT)) === BigInt(property);
- }
- return (this.mode & S_IFMT) === property;
-};
-
-Stats.prototype.isDirectory = function() {
+StatsBase.prototype.isDirectory = function() {
return this._checkModeProperty(S_IFDIR);
};
-Stats.prototype.isFile = function() {
+StatsBase.prototype.isFile = function() {
return this._checkModeProperty(S_IFREG);
};
-Stats.prototype.isBlockDevice = function() {
+StatsBase.prototype.isBlockDevice = function() {
return this._checkModeProperty(S_IFBLK);
};
-Stats.prototype.isCharacterDevice = function() {
+StatsBase.prototype.isCharacterDevice = function() {
return this._checkModeProperty(S_IFCHR);
};
-Stats.prototype.isSymbolicLink = function() {
+StatsBase.prototype.isSymbolicLink = function() {
return this._checkModeProperty(S_IFLNK);
};
-Stats.prototype.isFIFO = function() {
+StatsBase.prototype.isFIFO = function() {
return this._checkModeProperty(S_IFIFO);
};
-Stats.prototype.isSocket = function() {
+StatsBase.prototype.isSocket = function() {
return this._checkModeProperty(S_IFSOCK);
};
+const kNsPerMsBigInt = 10n ** 6n;
+const kNsPerSecBigInt = 10n ** 9n;
+const kMsPerSec = 10 ** 3;
+const kNsPerMs = 10 ** 6;
+function msFromTimeSpec(sec, nsec) {
+ return sec * kMsPerSec + nsec / kNsPerMs;
+}
+
+function nsFromTimeSpecBigInt(sec, nsec) {
+ return sec * kNsPerSecBigInt + nsec;
+}
+
+function dateFromMs(ms) {
+ return new Date(Number(ms) + 0.5);
+}
+
+function BigIntStats(dev, mode, nlink, uid, gid, rdev, blksize,
+ ino, size, blocks,
+ atimeNs, mtimeNs, ctimeNs, birthtimeNs) {
+ StatsBase.call(this, dev, mode, nlink, uid, gid, rdev, blksize,
+ ino, size, blocks);
+
+ this.atimeMs = atimeNs / kNsPerMsBigInt;
+ this.mtimeMs = mtimeNs / kNsPerMsBigInt;
+ this.ctimeMs = ctimeNs / kNsPerMsBigInt;
+ this.birthtimeMs = birthtimeNs / kNsPerMsBigInt;
+ this.atimeNs = atimeNs;
+ this.mtimeNs = mtimeNs;
+ this.ctimeNs = ctimeNs;
+ this.birthtimeNs = birthtimeNs;
+ this.atime = dateFromMs(this.atimeMs);
+ this.mtime = dateFromMs(this.mtimeMs);
+ this.ctime = dateFromMs(this.ctimeMs);
+ this.birthtime = dateFromMs(this.birthtimeMs);
+}
+
+Object.setPrototypeOf(BigIntStats.prototype, StatsBase.prototype);
+Object.setPrototypeOf(BigIntStats, StatsBase);
+
+BigIntStats.prototype._checkModeProperty = function(property) {
+ if (isWindows && (property === S_IFIFO || property === S_IFBLK ||
+ property === S_IFSOCK)) {
+ return false; // Some types are not available on Windows
+ }
+ return (this.mode & BigInt(S_IFMT)) === BigInt(property);
+};
+
+function Stats(dev, mode, nlink, uid, gid, rdev, blksize,
+ ino, size, blocks,
+ atimeMs, mtimeMs, ctimeMs, birthtimeMs) {
+ StatsBase.call(this, dev, mode, nlink, uid, gid, rdev, blksize,
+ ino, size, blocks);
+ this.atimeMs = atimeMs;
+ this.mtimeMs = mtimeMs;
+ this.ctimeMs = ctimeMs;
+ this.birthtimeMs = birthtimeMs;
+ this.atime = dateFromMs(atimeMs);
+ this.mtime = dateFromMs(mtimeMs);
+ this.ctime = dateFromMs(ctimeMs);
+ this.birthtime = dateFromMs(birthtimeMs);
+}
+
+Object.setPrototypeOf(Stats.prototype, StatsBase.prototype);
+Object.setPrototypeOf(Stats, StatsBase);
+
+Stats.prototype._checkModeProperty = function(property) {
+ if (isWindows && (property === S_IFIFO || property === S_IFBLK ||
+ property === S_IFSOCK)) {
+ return false; // Some types are not available on Windows
+ }
+ return (this.mode & S_IFMT) === property;
+};
+
function getStatsFromBinding(stats, offset = 0) {
- return new Stats(stats[0 + offset], stats[1 + offset], stats[2 + offset],
- stats[3 + offset], stats[4 + offset], stats[5 + offset],
- stats[6 + offset], // blksize
- stats[7 + offset], stats[8 + offset],
- stats[9 + offset], // blocks
- stats[10 + offset], stats[11 + offset],
- stats[12 + offset], stats[13 + offset]);
+ if (isBigUint64Array(stats)) {
+ return new BigIntStats(
+ stats[0 + offset], stats[1 + offset], stats[2 + offset],
+ stats[3 + offset], stats[4 + offset], stats[5 + offset],
+ stats[6 + offset], stats[7 + offset], stats[8 + offset],
+ stats[9 + offset],
+ nsFromTimeSpecBigInt(stats[10 + offset], stats[11 + offset]),
+ nsFromTimeSpecBigInt(stats[12 + offset], stats[13 + offset]),
+ nsFromTimeSpecBigInt(stats[14 + offset], stats[15 + offset]),
+ nsFromTimeSpecBigInt(stats[16 + offset], stats[17 + offset])
+ );
+ }
+ return new Stats(
+ stats[0 + offset], stats[1 + offset], stats[2 + offset],
+ stats[3 + offset], stats[4 + offset], stats[5 + offset],
+ stats[6 + offset], stats[7 + offset], stats[8 + offset],
+ stats[9 + offset],
+ msFromTimeSpec(stats[10 + offset], stats[11 + offset]),
+ msFromTimeSpec(stats[12 + offset], stats[13 + offset]),
+ msFromTimeSpec(stats[14 + offset], stats[15 + offset]),
+ msFromTimeSpec(stats[16 + offset], stats[17 + offset])
+ );
}
function stringToFlags(flags) {
@@ -453,6 +505,7 @@ function warnOnNonPortableTemplate(template) {
module.exports = {
assertEncoding,
+ BigIntStats, // for testing
copyObject,
Dirent,
getDirents,
diff --git a/src/env.h b/src/env.h
index fb54f5ee99..2f74adcc28 100644
--- a/src/env.h
+++ b/src/env.h
@@ -102,10 +102,32 @@ struct PackageConfig {
};
} // namespace loader
+enum class FsStatsOffset {
+ kDev = 0,
+ kMode,
+ kNlink,
+ kUid,
+ kGid,
+ kRdev,
+ kBlkSize,
+ kIno,
+ kSize,
+ kBlocks,
+ kATimeSec,
+ kATimeNsec,
+ kMTimeSec,
+ kMTimeNsec,
+ kCTimeSec,
+ kCTimeNsec,
+ kBirthTimeSec,
+ kBirthTimeNsec,
+ kFsStatsFieldsNumber
+};
+
// Stat fields buffers contain twice the number of entries in an uv_stat_t
// because `fs.StatWatcher` needs room to store 2 `fs.Stats` instances.
-constexpr size_t kFsStatsFieldsNumber = 14;
-constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
+constexpr size_t kFsStatsBufferLength =
+ static_cast<size_t>(FsStatsOffset::kFsStatsFieldsNumber) * 2;
// PER_ISOLATE_* macros: We have a lot of per-isolate properties
// and adding and maintaining their getters and setters by hand would be
diff --git a/src/node_file.cc b/src/node_file.cc
index 8f82d639d6..564c63bad7 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -2197,10 +2197,13 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "mkdtemp", Mkdtemp);
- target->Set(context,
- FIXED_ONE_BYTE_STRING(isolate, "kFsStatsFieldsNumber"),
- Integer::New(isolate, kFsStatsFieldsNumber))
- .Check();
+ target
+ ->Set(context,
+ FIXED_ONE_BYTE_STRING(isolate, "kFsStatsFieldsNumber"),
+ Integer::New(
+ isolate,
+ static_cast<int32_t>(FsStatsOffset::kFsStatsFieldsNumber)))
+ .Check();
target->Set(context,
FIXED_ONE_BYTE_STRING(isolate, "statValues"),
diff --git a/src/node_file.h b/src/node_file.h
index ae50a50b38..2ea5af025d 100644
--- a/src/node_file.h
+++ b/src/node_file.h
@@ -6,6 +6,7 @@
#include "node.h"
#include "stream_base.h"
#include "req_wrap-inl.h"
+#include <iostream>
namespace node {
@@ -149,74 +150,48 @@ class FSReqCallback : public FSReqBase {
FSReqCallback& operator=(const FSReqCallback&) = delete;
};
-// Wordaround a GCC4.9 bug that C++14 N3652 was not implemented
-// Refs: https://www.gnu.org/software/gcc/projects/cxx-status.html#cxx14
-// Refs: https://isocpp.org/files/papers/N3652.html
-#if __cpp_constexpr < 201304
-# define constexpr inline
-#endif
-
-template <typename NativeT,
- // SFINAE limit NativeT to arithmetic types
- typename = std::enable_if<std::is_arithmetic<NativeT>::value>>
-constexpr NativeT ToNative(uv_timespec_t ts) {
- // This template has exactly two specializations below.
- static_assert(std::is_arithmetic<NativeT>::value == false, "Not implemented");
- return NativeT();
-}
-
-template <>
-constexpr double ToNative(uv_timespec_t ts) {
- // We need to do a static_cast since the original FS values are ulong.
- /* NOLINTNEXTLINE(runtime/int) */
- const auto u_sec = static_cast<unsigned long>(ts.tv_sec);
- const double full_sec = u_sec * 1000.0;
- /* NOLINTNEXTLINE(runtime/int) */
- const auto u_nsec = static_cast<unsigned long>(ts.tv_nsec);
- const double full_nsec = u_nsec / 1000'000.0;
- return full_sec + full_nsec;
-}
-
-template <>
-constexpr uint64_t ToNative(uv_timespec_t ts) {
- // We need to do a static_cast since the original FS values are ulong.
- /* NOLINTNEXTLINE(runtime/int) */
- const auto u_sec = static_cast<unsigned long>(ts.tv_sec);
- const auto full_sec = static_cast<uint64_t>(u_sec) * 1000UL;
- /* NOLINTNEXTLINE(runtime/int) */
- const auto u_nsec = static_cast<unsigned long>(ts.tv_nsec);
- const auto full_nsec = static_cast<uint64_t>(u_nsec) / 1000'000UL;
- return full_sec + full_nsec;
-}
-
-#undef constexpr // end N3652 bug workaround
-
template <typename NativeT, typename V8T>
constexpr void FillStatsArray(AliasedBufferBase<NativeT, V8T>* fields,
const uv_stat_t* s,
const size_t offset = 0) {
- fields->SetValue(offset + 0, static_cast<NativeT>(s->st_dev));
- fields->SetValue(offset + 1, static_cast<NativeT>(s->st_mode));
- fields->SetValue(offset + 2, static_cast<NativeT>(s->st_nlink));
- fields->SetValue(offset + 3, static_cast<NativeT>(s->st_uid));
- fields->SetValue(offset + 4, static_cast<NativeT>(s->st_gid));
- fields->SetValue(offset + 5, static_cast<NativeT>(s->st_rdev));
- fields->SetValue(offset + 6, static_cast<NativeT>(s->st_blksize));
- fields->SetValue(offset + 7, static_cast<NativeT>(s->st_ino));
- fields->SetValue(offset + 8, static_cast<NativeT>(s->st_size));
- fields->SetValue(offset + 9, static_cast<NativeT>(s->st_blocks));
-// Dates.
- fields->SetValue(offset + 10, ToNative<NativeT>(s->st_atim));
- fields->SetValue(offset + 11, ToNative<NativeT>(s->st_mtim));
- fields->SetValue(offset + 12, ToNative<NativeT>(s->st_ctim));
- fields->SetValue(offset + 13, ToNative<NativeT>(s->st_birthtim));
+#define SET_FIELD_WITH_STAT(stat_offset, stat) \
+ fields->SetValue(offset + static_cast<size_t>(FsStatsOffset::stat_offset), \
+ static_cast<NativeT>(stat))
+
+#define SET_FIELD_WITH_TIME_STAT(stat_offset, stat) \
+ /* NOLINTNEXTLINE(runtime/int) */ \
+ SET_FIELD_WITH_STAT(stat_offset, static_cast<unsigned long>(stat))
+
+ SET_FIELD_WITH_STAT(kDev, s->st_dev);
+ SET_FIELD_WITH_STAT(kMode, s->st_mode);
+ SET_FIELD_WITH_STAT(kNlink, s->st_nlink);
+ SET_FIELD_WITH_STAT(kUid, s->st_uid);
+ SET_FIELD_WITH_STAT(kGid, s->st_gid);
+ SET_FIELD_WITH_STAT(kRdev, s->st_rdev);
+ SET_FIELD_WITH_STAT(kBlkSize, s->st_blksize);
+ SET_FIELD_WITH_STAT(kIno, s->st_ino);
+ SET_FIELD_WITH_STAT(kSize, s->st_size);
+ SET_FIELD_WITH_STAT(kBlocks, s->st_blocks);
+
+ SET_FIELD_WITH_TIME_STAT(kATimeSec, s->st_atim.tv_sec);
+ SET_FIELD_WITH_TIME_STAT(kATimeNsec, s->st_atim.tv_nsec);
+ SET_FIELD_WITH_TIME_STAT(kMTimeSec, s->st_mtim.tv_sec);
+ SET_FIELD_WITH_TIME_STAT(kMTimeNsec, s->st_mtim.tv_nsec);
+ SET_FIELD_WITH_TIME_STAT(kCTimeSec, s->st_ctim.tv_sec);
+ SET_FIELD_WITH_TIME_STAT(kCTimeNsec, s->st_ctim.tv_nsec);
+ SET_FIELD_WITH_TIME_STAT(kBirthTimeSec, s->st_birthtim.tv_sec);
+ SET_FIELD_WITH_TIME_STAT(kBirthTimeNsec, s->st_birthtim.tv_nsec);
+
+#undef SET_FIELD_WITH_TIME_STAT
+#undef SET_FIELD_WITH_STAT
}
inline Local<Value> FillGlobalStatsArray(Environment* env,
const bool use_bigint,
const uv_stat_t* s,
const bool second = false) {
- const ptrdiff_t offset = second ? kFsStatsFieldsNumber : 0;
+ const ptrdiff_t offset =
+ second ? static_cast<ptrdiff_t>(FsStatsOffset::kFsStatsFieldsNumber) : 0;
if (use_bigint) {
auto* const arr = env->fs_stats_field_bigint_array();
FillStatsArray(arr, s, offset);
@@ -302,7 +277,9 @@ class FSReqPromise : public FSReqBase {
private:
FSReqPromise(Environment* env, v8::Local<v8::Object> obj, bool use_bigint)
: FSReqBase(env, obj, AsyncWrap::PROVIDER_FSREQPROMISE, use_bigint),
- stats_field_array_(env->isolate(), kFsStatsFieldsNumber) {}
+ stats_field_array_(
+ env->isolate(),
+ static_cast<size_t>(FsStatsOffset::kFsStatsFieldsNumber)) {}
bool finished_ = false;
AliasedBufferT stats_field_array_;
diff --git a/test/parallel/test-fs-stat-bigint.js b/test/parallel/test-fs-stat-bigint.js
index d004112680..998ddb289d 100644
--- a/test/parallel/test-fs-stat-bigint.js
+++ b/test/parallel/test-fs-stat-bigint.js
@@ -59,6 +59,26 @@ function verifyStats(bigintStats, numStats) {
bigintStats.isSymbolicLink(),
numStats.isSymbolicLink()
);
+ } else if (key.endsWith('Ms')) {
+ const nsKey = key.replace('Ms', 'Ns');
+ const msFromBigInt = bigintStats[key];
+ const nsFromBigInt = bigintStats[nsKey];
+ const msFromBigIntNs = Number(nsFromBigInt / (10n ** 6n));
+ const msFromNum = numStats[key];
+ // The difference between the millisecond-precision values should be
+ // smaller than 2
+ assert(
+ Math.abs(msFromNum - Number(msFromBigInt)) < 2,
+ `Number version ${key} = ${msFromNum}, ` +
+ `BigInt version ${key} = ${msFromBigInt}n`);
+ // The difference between the millisecond-precision value and the
+ // nanosecond-precision value scaled down to milliseconds should be
+ // smaller than 2
+ assert(
+ Math.abs(msFromNum - Number(msFromBigIntNs)) < 2,
+ `Number version ${key} = ${msFromNum}, ` +
+ `BigInt version ${nsKey} = ${nsFromBigInt}n` +
+ ` = ${msFromBigIntNs}ms`);
} else if (Number.isSafeInteger(val)) {
assert.strictEqual(
bigintStats[key], BigInt(val),
diff --git a/test/parallel/test-fs-watchfile-bigint.js b/test/parallel/test-fs-watchfile-bigint.js
index d5528bb2d3..500a0ef1f6 100644
--- a/test/parallel/test-fs-watchfile-bigint.js
+++ b/test/parallel/test-fs-watchfile-bigint.js
@@ -1,14 +1,18 @@
'use strict';
+
+// Flags: --expose-internals
+
const common = require('../common');
const assert = require('assert');
+const { BigIntStats } = require('internal/fs/utils');
const fs = require('fs');
const path = require('path');
const tmpdir = require('../common/tmpdir');
const enoentFile = path.join(tmpdir.path, 'non-existent-file');
-const expectedStatObject = new fs.Stats(
+const expectedStatObject = new BigIntStats(
0n, // dev
0n, // mode
0n, // nlink
@@ -19,10 +23,14 @@ const expectedStatObject = new fs.Stats(
0n, // ino
0n, // size
0n, // blocks
- 0n, // atim_msec
- 0n, // mtim_msec
- 0n, // ctim_msec
- 0n // birthtim_msec
+ 0n, // atimeMs
+ 0n, // mtimeMs
+ 0n, // ctimeMs
+ 0n, // birthtimeMs
+ 0n, // atimeNs
+ 0n, // mtimeNs
+ 0n, // ctimeNs
+ 0n // birthtimeNs
);
tmpdir.refresh();