diff options
author | 2022-07-20 12:19:41 -0500 | |
---|---|---|
committer | 2022-07-20 10:19:41 -0700 | |
commit | 7500f4b2cae329719d2b71098ffdc93735c764bf (patch) | |
tree | 2af7667fc8113d0140edbb99771dd8fde8cb2baa | |
parent | 08bff8e09035dff15cb0e8333e9a5f1c9b10ea0d (diff) | |
download | bun-7500f4b2cae329719d2b71098ffdc93735c764bf.tar.gz bun-7500f4b2cae329719d2b71098ffdc93735c764bf.tar.zst bun-7500f4b2cae329719d2b71098ffdc93735c764bf.zip |
feat(node/fs): implement more stat methods (#807)
-rw-r--r-- | src/bun.js/node/types.zig | 51 | ||||
l--------- | test/bun.js/fs-stream.link.js | 1 | ||||
-rw-r--r-- | test/bun.js/fs.test.js | 61 |
3 files changed, 108 insertions, 5 deletions
diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 2e704037e..18d437d76 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -797,7 +797,7 @@ pub const FileSystemFlags = enum(Mode) { } }; -/// Milliseconds precision +/// Milliseconds precision pub const Date = enum(u64) { _, @@ -818,12 +818,27 @@ fn StatsLike(comptime name: [:0]const u8, comptime T: type) type { This, .{ .name = name }, .{ - .isFile = .{ - .rfn = JSC.wrap(This, "isFile", false), + .isBlockDevice = .{ + .rfn = JSC.wrap(This, "isBlockDevice", false), + }, + .isCharacterDevice = .{ + .rfn = JSC.wrap(This, "isCharacterDevice", false), }, .isDirectory = .{ .rfn = JSC.wrap(This, "isDirectory", false), }, + .isFIFO = .{ + .rfn = JSC.wrap(This, "isFIFO", false), + }, + .isFile = .{ + .rfn = JSC.wrap(This, "isFile", false), + }, + .isSocket = .{ + .rfn = JSC.wrap(This, "isSocket", false), + }, + .isSymbolicLink = .{ + .rfn = JSC.wrap(This, "isSymbolicLink", false), + }, .finalize = finalize, }, .{ @@ -957,13 +972,39 @@ fn StatsLike(comptime name: [:0]const u8, comptime T: type) type { }; } - pub fn isFile(this: *Stats) JSC.JSValue { - return JSC.JSValue.jsBoolean(os.S.ISREG(@intCast(Mode, this.mode))); + pub fn isBlockDevice(this: *Stats) JSC.JSValue { + return JSC.JSValue.jsBoolean(os.S.ISBLK(@intCast(Mode, this.mode))); + } + + pub fn isCharacterDevice(this: *Stats) JSC.JSValue { + return JSC.JSValue.jsBoolean(os.S.ISCHR(@intCast(Mode, this.mode))); } + pub fn isDirectory(this: *Stats) JSC.JSValue { return JSC.JSValue.jsBoolean(os.S.ISDIR(@intCast(Mode, this.mode))); } + pub fn isFIFO(this: *Stats) JSC.JSValue { + return JSC.JSValue.jsBoolean(os.S.ISFIFO(@intCast(Mode, this.mode))); + } + + pub fn isFile(this: *Stats) JSC.JSValue { + return JSC.JSValue.jsBoolean(os.S.ISREG(@intCast(Mode, this.mode))); + } + + pub fn isSocket(this: *Stats) JSC.JSValue { + return JSC.JSValue.jsBoolean(os.S.ISSOCK(@intCast(Mode, this.mode))); + } + + // Node.js says this method is only valid on the result of lstat() + // so it's fine if we just include it on stat() because it would + // still just return false. + // + // See https://nodejs.org/api/fs.html#statsissymboliclink + pub fn isSymbolicLink(this: *Stats) JSC.JSValue { + return JSC.JSValue.jsBoolean(os.S.ISLNK(@intCast(Mode, this.mode))); + } + pub fn toJS(this: Stats, ctx: JSC.C.JSContextRef, _: JSC.C.ExceptionRef) JSC.C.JSValueRef { var _this = bun.default_allocator.create(Stats) catch unreachable; _this.* = this; diff --git a/test/bun.js/fs-stream.link.js b/test/bun.js/fs-stream.link.js new file mode 120000 index 000000000..0cadae0e5 --- /dev/null +++ b/test/bun.js/fs-stream.link.js @@ -0,0 +1 @@ +./test/bun.js/fs-stream.js
\ No newline at end of file diff --git a/test/bun.js/fs.test.js b/test/bun.js/fs.test.js index 79ac60eaa..d3c6be901 100644 --- a/test/bun.js/fs.test.js +++ b/test/bun.js/fs.test.js @@ -11,6 +11,8 @@ import { readSync, writeFileSync, writeSync, + statSync, + lstatSync, } from "node:fs"; const Buffer = globalThis.Buffer || Uint8Array; @@ -242,3 +244,62 @@ describe("writeFileSync", () => { } }); }); + +describe("lstat", () => { + it("file metadata is correct", () => { + const fileStats = lstatSync( + new URL("./fs-stream.js", import.meta.url) + .toString() + .slice("file://".length - 1) + ); + expect(fileStats.isSymbolicLink()).toBe(false); + expect(fileStats.isFile()).toBe(true); + expect(fileStats.isDirectory()).toBe(false); + }); + + it("folder metadata is correct", () => { + const fileStats = lstatSync( + new URL("../../test", import.meta.url) + .toString() + .slice("file://".length - 1) + ); + expect(fileStats.isSymbolicLink()).toBe(false); + expect(fileStats.isFile()).toBe(false); + expect(fileStats.isDirectory()).toBe(true); + }); + + it("symlink metadata is correct", () => { + const linkStats = lstatSync( + new URL("./fs-stream.link.js", import.meta.url) + .toString() + .slice("file://".length - 1) + ); + expect(linkStats.isSymbolicLink()).toBe(true); + expect(linkStats.isFile()).toBe(false); + expect(linkStats.isDirectory()).toBe(false); + }); +}); + +describe("stat", () => { + it("file metadata is correct", () => { + const fileStats = statSync( + new URL("./fs-stream.js", import.meta.url) + .toString() + .slice("file://".length - 1) + ); + expect(fileStats.isSymbolicLink()).toBe(false); + expect(fileStats.isFile()).toBe(true); + expect(fileStats.isDirectory()).toBe(false); + }); + + it("folder metadata is correct", () => { + const fileStats = statSync( + new URL("../../test", import.meta.url) + .toString() + .slice("file://".length - 1) + ); + expect(fileStats.isSymbolicLink()).toBe(false); + expect(fileStats.isFile()).toBe(false); + expect(fileStats.isDirectory()).toBe(true); + }); +}); |