From 2b77f81e2f4a87e822eda884317477a7b589280e Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Sun, 10 Dec 2023 21:49:13 -0500 Subject: [PATCH 01/13] Prep for adding path to Dirent three locations in node_fs.zig are apparently where code changes are needed. Should also check to see if there are tests to add. --- packages/bun-types/fs.d.ts | 5 +++++ src/bun.js/node/node.classes.ts | 4 ++++ src/bun.js/node/node_fs.zig | 3 +++ src/bun.js/node/types.zig | 5 +++++ 4 files changed, 17 insertions(+) diff --git a/packages/bun-types/fs.d.ts b/packages/bun-types/fs.d.ts index a8e3d11be4b6f0..6a2e09d2672535 100644 --- a/packages/bun-types/fs.d.ts +++ b/packages/bun-types/fs.d.ts @@ -176,6 +176,11 @@ declare module "fs" { * @since v0.0.67 */ name: string; + /** + * The base path that this `fs.Dirent` object refers to. + * @since v1.0.17 + */ + path: string; } /** diff --git a/src/bun.js/node/node.classes.ts b/src/bun.js/node/node.classes.ts index 0cde536a2d1083..b9b54fe1b0f32f 100644 --- a/src/bun.js/node/node.classes.ts +++ b/src/bun.js/node/node.classes.ts @@ -429,6 +429,10 @@ export default [ getter: "getName", cache: true, }, + path: { + getter: "getPath", + cache: true, + }, }, }), define({ diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index c8dce34f78b2bb..ef901e08097ced 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -4549,6 +4549,7 @@ pub const NodeFS = struct { Dirent => { entries.append(.{ .name = bun.String.create(utf8_name), + .path = bun.String.create(utf8_name), .kind = current.kind, }) catch bun.outOfMemory(); }, @@ -4668,6 +4669,7 @@ pub const NodeFS = struct { Dirent => { entries.append(.{ .name = bun.String.create(name_to_copy), + .path = bun.String.create(name_to_copy), .kind = current.kind, }) catch bun.outOfMemory(); }, @@ -4797,6 +4799,7 @@ pub const NodeFS = struct { Dirent => { entries.append(.{ .name = bun.String.create(name_to_copy), + .path = bun.String.create(name_to_copy), .kind = current.kind, }) catch bun.outOfMemory(); }, diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 9418fb67fb4405..e0360e82d4ef46 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -1728,6 +1728,7 @@ pub const Stats = union(enum) { /// @since v12.12.0 pub const Dirent = struct { name: bun.String, + path: bun.String, // not publicly exposed kind: Kind, @@ -1743,6 +1744,10 @@ pub const Dirent = struct { return this.name.toJS(globalObject); } + pub fn getPath(this: *Dirent, globalObject: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue { + return this.path.toJS(globalObject); + } + pub fn isBlockDevice( this: *Dirent, _: *JSC.JSGlobalObject, From f52535a63ca340a5082f22f208926a9e182f9dc8 Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Mon, 11 Dec 2023 19:16:39 -0500 Subject: [PATCH 02/13] Use std.fs.path to get path basename and dirname --- src/bun.js/node/node_fs.zig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index ef901e08097ced..a0492948609aab 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -4548,8 +4548,8 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { entries.append(.{ - .name = bun.String.create(utf8_name), - .path = bun.String.create(utf8_name), + .name = bun.String.create(std.fs.path.basename(utf8_name)), + .path = bun.String.create(std.fs.path.dirname(utf8_name) orelse utf8_name), .kind = current.kind, }) catch bun.outOfMemory(); }, @@ -4668,8 +4668,8 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { entries.append(.{ - .name = bun.String.create(name_to_copy), - .path = bun.String.create(name_to_copy), + .name = bun.String.create(std.fs.path.basename(name_to_copy)), + .path = bun.String.create(std.fs.path.dirname(name_to_copy) orelse name_to_copy), .kind = current.kind, }) catch bun.outOfMemory(); }, @@ -4798,8 +4798,8 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { entries.append(.{ - .name = bun.String.create(name_to_copy), - .path = bun.String.create(name_to_copy), + .name = bun.String.create(std.fs.path.basename(name_to_copy)), + .path = bun.String.create(std.fs.path.dirname(name_to_copy) orelse name_to_copy), .kind = current.kind, }) catch bun.outOfMemory(); }, From ebacf48393a994dcd80539ca1603fa76cdd9ac64 Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Mon, 11 Dec 2023 21:25:19 -0500 Subject: [PATCH 03/13] Probably supposed to deref these since they're new strings --- src/bun.js/node/node_fs.zig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index a0492948609aab..9f42ecb735e5c0 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -363,6 +363,7 @@ pub const AsyncReaddirRecursiveTask = struct { .with_file_types => |*res| { for (res.items) |item| { item.name.deref(); + item.path.deref(); } res.clearAndFree(); }, @@ -479,7 +480,10 @@ pub const AsyncReaddirRecursiveTask = struct { for (entries.items) |*item| { switch (comptime ResultType) { bun.String => item.deref(), - Dirent => item.name.deref(), + Dirent => { + item.name.deref(); + item.path.deref(); + }, Buffer => bun.default_allocator.free(item.buffer.byteSlice()), else => unreachable, } @@ -4525,6 +4529,7 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { item.name.deref(); + item.path.deref(); }, Buffer => { item.destroy(); @@ -4842,6 +4847,7 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { result.name.deref(); + result.path.deref(); }, Buffer => { result.destroy(); From 141b03f1cb89ddd6b79c7f37d1e8ff45bfa77ccd Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Tue, 12 Dec 2023 20:33:16 -0500 Subject: [PATCH 04/13] Testing file for research purposes This is not the right place for this --- test/dirent.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/dirent.js diff --git a/test/dirent.js b/test/dirent.js new file mode 100644 index 00000000000000..a8e14dc5d656db --- /dev/null +++ b/test/dirent.js @@ -0,0 +1,33 @@ +// This script tests the contents of fs.Dirent for all of the methods that return it. +// Compare running with node vs. running with Bun for compatibility. + +const fs = require('fs'); + +// From the working directory, create a collection of files and folders for testing. +const target = process.argv[2]; + +// pass arguments: +// /tmp/test +// ./test +// test +// . +// ../../test +// .. + +// path is always identical to the argument except for recursive entries +// For recursed entries, a leading `./` is not included + +fs.mkdirSync(target + '/subfolder/childfolder', { recursive: true }); +fs.writeFileSync(target + '/file.txt', 'test'); +fs.writeFileSync(target + '/subfolder/childfile.txt', 'test'); + +let results = {}; +function mapFiles(files) { + return files.map(f => ({ name: f.name, path: f.path })) + .toSorted((a, b) => a.path+'/'+a.name < b.path+'/'+b.name); +} + +results['fs.readdirSync'] = mapFiles(fs.readdirSync(target, { withFileTypes: true })); +results['fs.readdirSync recursive'] = mapFiles(fs.readdirSync(target, { withFileTypes: true, recursive: true })); + +console.log(results); From 52ebf5f5a1c8ff5cd72f3eac90a134234aa88f2c Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Tue, 12 Dec 2023 22:11:19 -0500 Subject: [PATCH 05/13] Properly(?) added direntry paths for non-recursive variant I believe `path` is always the passed-in relative or absolute path in this case --- src/bun.js/node/node_fs.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 9f42ecb735e5c0..65fb065f00671f 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -346,7 +346,7 @@ pub const AsyncReaddirRecursiveTask = struct { /// All the subtasks will use this fd to open files root_fd: FileDescriptor = bun.invalid_fd, - /// This isued when joining the file paths for error messages + /// This is used when joining the file paths for error messages root_path: PathString = PathString.empty, pending_err: ?Syscall.Error = null, @@ -4553,8 +4553,8 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { entries.append(.{ - .name = bun.String.create(std.fs.path.basename(utf8_name)), - .path = bun.String.create(std.fs.path.dirname(utf8_name) orelse utf8_name), + .name = bun.String.create(utf8_name), + .path = bun.String.create(args.path.slice()), .kind = current.kind, }) catch bun.outOfMemory(); }, From 1cd702806d86ff913b7aca307ff2b8dc393387d0 Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Tue, 12 Dec 2023 22:29:25 -0500 Subject: [PATCH 06/13] Added async recursive variant to test script To test all three of Bun's withFileTypes implementations --- test/dirent.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/dirent.js b/test/dirent.js index a8e14dc5d656db..08e8d51a2e1cf1 100644 --- a/test/dirent.js +++ b/test/dirent.js @@ -29,5 +29,9 @@ function mapFiles(files) { results['fs.readdirSync'] = mapFiles(fs.readdirSync(target, { withFileTypes: true })); results['fs.readdirSync recursive'] = mapFiles(fs.readdirSync(target, { withFileTypes: true, recursive: true })); +fs.promises.readdir(target, { withFileTypes: true, recursive: true }) + .then(files => { + results['fs.promises.readdir recursive'] = mapFiles(files); + console.log(results); + }); -console.log(results); From 43c13caf6f3cfd902751487281620ebbb1bf3379 Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Wed, 13 Dec 2023 21:28:52 -0500 Subject: [PATCH 07/13] Recursive sync version works? --- src/bun.js/node/node_fs.zig | 21 ++++++++++++++++----- test/dirent.js | 3 ++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 65fb065f00671f..995a0201ab4f36 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -4673,8 +4673,8 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { entries.append(.{ - .name = bun.String.create(std.fs.path.basename(name_to_copy)), - .path = bun.String.create(std.fs.path.dirname(name_to_copy) orelse name_to_copy), + .name = bun.String.create(utf8_name), + .path = bun.String.create(name_to_copy), .kind = current.kind, }) catch bun.outOfMemory(); }, @@ -4693,6 +4693,7 @@ pub const NodeFS = struct { fn readdirWithEntriesRecursiveSync( buf: *[bun.MAX_PATH_BYTES]u8, + path_buf: *[bun.MAX_PATH_BYTES]u8, args: Arguments.Readdir, root_basename: [:0]const u8, comptime ExpectedType: type, @@ -4784,6 +4785,15 @@ pub const NodeFS = struct { break :brk bun.path.joinZBuf(buf, &path_parts, .auto); }; + const dirent_path_to_copy = brk: { + if (root_basename.ptr == basename.ptr) { + break :brk args.path.slice(); + } + + const path_parts = [_]string{ args.path.slice(), name_to_copy }; + break :brk std.fs.path.dirname(bun.path.joinZBuf(path_buf, &path_parts, .auto)) orelse args.path.slice(); + }; + enqueue: { switch (current.kind) { // a symlink might be a directory or might not be @@ -4803,8 +4813,8 @@ pub const NodeFS = struct { switch (comptime ExpectedType) { Dirent => { entries.append(.{ - .name = bun.String.create(std.fs.path.basename(name_to_copy)), - .path = bun.String.create(std.fs.path.dirname(name_to_copy) orelse name_to_copy), + .name = bun.String.create(utf8_name), + .path = bun.String.create(dirent_path_to_copy), .kind = current.kind, }) catch bun.outOfMemory(); }, @@ -4839,9 +4849,10 @@ pub const NodeFS = struct { var path = args.path.sliceZ(buf); if (comptime recursive and flavor == .sync) { var buf_to_pass: [bun.MAX_PATH_BYTES]u8 = undefined; + var path_buf_to_pass: [bun.MAX_PATH_BYTES]u8 = undefined; var entries = std.ArrayList(ExpectedType).init(bun.default_allocator); - return switch (readdirWithEntriesRecursiveSync(&buf_to_pass, args, path, ExpectedType, &entries)) { + return switch (readdirWithEntriesRecursiveSync(&buf_to_pass, &path_buf_to_pass, args, path, ExpectedType, &entries)) { .err => |err| { for (entries.items) |*result| { switch (comptime ExpectedType) { diff --git a/test/dirent.js b/test/dirent.js index 08e8d51a2e1cf1..1c3876da1098eb 100644 --- a/test/dirent.js +++ b/test/dirent.js @@ -17,9 +17,10 @@ const target = process.argv[2]; // path is always identical to the argument except for recursive entries // For recursed entries, a leading `./` is not included -fs.mkdirSync(target + '/subfolder/childfolder', { recursive: true }); +fs.mkdirSync(target + '/subfolder/childfolder/grandchildfolder', { recursive: true }); fs.writeFileSync(target + '/file.txt', 'test'); fs.writeFileSync(target + '/subfolder/childfile.txt', 'test'); +fs.writeFileSync(target + '/subfolder/childfolder/grandchildfile.txt', 'test'); let results = {}; function mapFiles(files) { From 64bfef380c404a1a358953276dc8433651f170a2 Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Wed, 13 Dec 2023 21:55:54 -0500 Subject: [PATCH 08/13] Async recursive version working?? --- packages/bun-types/fs.d.ts | 2 +- src/bun.js/node/node_fs.zig | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/bun-types/fs.d.ts b/packages/bun-types/fs.d.ts index 6a2e09d2672535..291ecc35a82c1e 100644 --- a/packages/bun-types/fs.d.ts +++ b/packages/bun-types/fs.d.ts @@ -178,7 +178,7 @@ declare module "fs" { name: string; /** * The base path that this `fs.Dirent` object refers to. - * @since v1.0.17 + * @since v?????? */ path: string; } diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 995a0201ab4f36..f9a57d86c4bb8e 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -401,7 +401,8 @@ pub const AsyncReaddirRecursiveTask = struct { bun.default_allocator.destroy(this); } var buf: [bun.MAX_PATH_BYTES]u8 = undefined; - this.readdir_task.performWork(this.basename.sliceAssumeZ(), &buf, false); + var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + this.readdir_task.performWork(this.basename.sliceAssumeZ(), &buf, &path_buf, false); } }; @@ -452,7 +453,13 @@ pub const AsyncReaddirRecursiveTask = struct { return task.promise.value(); } - pub fn performWork(this: *AsyncReaddirRecursiveTask, basename: [:0]const u8, buf: *[bun.MAX_PATH_BYTES]u8, comptime is_root: bool) void { + pub fn performWork( + this: *AsyncReaddirRecursiveTask, + basename: [:0]const u8, + buf: *[bun.MAX_PATH_BYTES]u8, + path_buf: *[bun.MAX_PATH_BYTES]u8, + comptime is_root: bool + ) void { switch (this.args.tag()) { inline else => |tag| { const ResultType = comptime switch (tag) { @@ -469,6 +476,7 @@ pub const AsyncReaddirRecursiveTask = struct { switch (NodeFS.readdirWithEntriesRecursiveAsync( buf, + path_buf, this.args, this, basename, @@ -513,7 +521,8 @@ pub const AsyncReaddirRecursiveTask = struct { fn workPoolCallback(task: *JSC.WorkPoolTask) void { var this: *AsyncReaddirRecursiveTask = @fieldParentPtr(AsyncReaddirRecursiveTask, "task", task); var buf: [bun.MAX_PATH_BYTES]u8 = undefined; - this.performWork(this.root_path.sliceAssumeZ(), &buf, true); + var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + this.performWork(this.root_path.sliceAssumeZ(), &buf, &path_buf, true); } pub fn writeResults(this: *AsyncReaddirRecursiveTask, comptime ResultType: type, result: *std.ArrayList(ResultType)) void { @@ -4573,6 +4582,7 @@ pub const NodeFS = struct { pub fn readdirWithEntriesRecursiveAsync( buf: *[bun.MAX_PATH_BYTES]u8, + path_buf: *[bun.MAX_PATH_BYTES]u8, args: Arguments.Readdir, async_task: *AsyncReaddirRecursiveTask, basename: [:0]const u8, @@ -4647,6 +4657,15 @@ pub const NodeFS = struct { break :brk bun.path.joinZBuf(buf, &path_parts, .auto); }; + const dirent_path_to_copy = brk: { + if (async_task.root_path.sliceAssumeZ().ptr == basename.ptr) { + break :brk args.path.slice(); + } + + const path_parts = [_]string{ args.path.slice(), name_to_copy }; + break :brk std.fs.path.dirname(bun.path.joinZBuf(path_buf, &path_parts, .auto)) orelse args.path.slice(); + }; + enqueue: { switch (current.kind) { // a symlink might be a directory or might not be @@ -4674,7 +4693,7 @@ pub const NodeFS = struct { Dirent => { entries.append(.{ .name = bun.String.create(utf8_name), - .path = bun.String.create(name_to_copy), + .path = bun.String.create(dirent_path_to_copy), .kind = current.kind, }) catch bun.outOfMemory(); }, From f3f34aa6d950aff5c02c29d76fb0da7aec42b4de Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Thu, 14 Dec 2023 21:11:13 -0500 Subject: [PATCH 09/13] Add parentPath alias for path getter. --- packages/bun-types/fs.d.ts | 6 ++++++ src/bun.js/node/node.classes.ts | 4 ++++ test/dirent.js | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/bun-types/fs.d.ts b/packages/bun-types/fs.d.ts index b0a5558675aea4..bed60b8831054c 100644 --- a/packages/bun-types/fs.d.ts +++ b/packages/bun-types/fs.d.ts @@ -178,9 +178,15 @@ declare module "fs" { name: string; /** * The base path that this `fs.Dirent` object refers to. + * Deprecated in favor of `parentPath`. * @since v?????? */ path: string; + /** + * The base path that this `fs.Dirent` object refers to. + * @since v?????? + */ + parentPath: string; } /** diff --git a/src/bun.js/node/node.classes.ts b/src/bun.js/node/node.classes.ts index b9b54fe1b0f32f..0baf9cb9ca7870 100644 --- a/src/bun.js/node/node.classes.ts +++ b/src/bun.js/node/node.classes.ts @@ -433,6 +433,10 @@ export default [ getter: "getPath", cache: true, }, + parentPath: { + getter: "getPath", + cache: true, + }, }, }), define({ diff --git a/test/dirent.js b/test/dirent.js index 1c3876da1098eb..4e333105c377ff 100644 --- a/test/dirent.js +++ b/test/dirent.js @@ -24,7 +24,7 @@ fs.writeFileSync(target + '/subfolder/childfolder/grandchildfile.txt', 'test'); let results = {}; function mapFiles(files) { - return files.map(f => ({ name: f.name, path: f.path })) + return files.map(f => ({ name: f.name, path: f.path, parentPath: f.parentPath })) .toSorted((a, b) => a.path+'/'+a.name < b.path+'/'+b.name); } From ab38aa2c42b1a3ef94120f38638da54f508ebffa Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Sun, 17 Dec 2023 19:42:52 -0500 Subject: [PATCH 10/13] Fix intended template literal --- test/js/node/fs/fs.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/js/node/fs/fs.test.ts b/test/js/node/fs/fs.test.ts index d9af8aba0e0f55..7980fa24a88cb4 100644 --- a/test/js/node/fs/fs.test.ts +++ b/test/js/node/fs/fs.test.ts @@ -991,7 +991,7 @@ describe("stat", () => { it("stat returns ENOENT", () => { try { - statSync("${tmpdir()}/doesntexist"); + statSync(`${tmpdir()}/doesntexist`); throw "statSync should throw"; } catch (e: any) { expect(e.code).toBe("ENOENT"); From ba856cfb8f85e52437d2c2a7860693fb8eecd9ab Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Sun, 17 Dec 2023 22:20:09 -0500 Subject: [PATCH 11/13] Add tests for Dirent name/path values --- test/js/node/fs/fs.test.ts | 58 +++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/test/js/node/fs/fs.test.ts b/test/js/node/fs/fs.test.ts index 7980fa24a88cb4..bd510719cbc84d 100644 --- a/test/js/node/fs/fs.test.ts +++ b/test/js/node/fs/fs.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "bun:test"; +import { describe, expect, it, beforeEach } from "bun:test"; import { dirname, resolve, relative } from "node:path"; import { promisify } from "node:util"; import { bunEnv, bunExe, gc } from "harness"; @@ -66,6 +66,20 @@ it("Dirent.name setter", () => { expect(dirent.name).toBe("hello"); }); +it("Dirent.path setter", () => { + const dirent = Object.create(Dirent.prototype); + expect(dirent.path).toBeUndefined(); + dirent.path = "hello"; + expect(dirent.path).toBe("hello"); +}); + +it("Dirent.parentPath setter", () => { + const dirent = Object.create(Dirent.prototype); + expect(dirent.parentPath).toBeUndefined(); + dirent.parentPath = "hello"; + expect(dirent.parentPath).toBe("hello"); +}); + it("writeFileSync in append should not truncate the file", () => { const path = join(tmpdir(), "writeFileSync-should-not-append-" + (Date.now() * 10000).toString(16)); var str = ""; @@ -2469,3 +2483,45 @@ it.if(isWindows)("writing to windows hidden file is possible", () => { const content = readFileSync("file.txt", "utf8"); expect(content).toBe("Hello World"); }); + +describe("Dirent name and path values", () => { + const dirPath = `${tmpdir()}/Bun-fs-readdir-dirent`; + beforeEach(() => { + rmSync(dirPath, { recursive: true }); + mkdirSync(dirPath, { recursive: true }); + }); + describe("nonrecursive readdir", () => { + it("should return the correct name and path values for directory", () => { + const path = join(dirPath, 'directory'); + mkdirSync(path, { recursive: true }); + const entries = readdirSync(dirPath, { withFileTypes: true }); + expect(entries[0].name).toBe('directory'); + expect(entries[0].path).toBe(dirPath); + }); + it("should return the correct name and path values for file", () => { + const path = join(dirPath, 'file.txt') + writeFileSync(path, 'Hello World'); + const entries = readdirSync(dirPath, { withFileTypes: true }); + expect(entries[0].name).toBe('file.txt'); + expect(entries[0].path).toBe(dirPath); + }); + }); + describe("recursive readdirSync", () => { + it("should return the correct path values for directory and subdirectory", () => { + const path = join(dirPath, 'directory', 'subdirectory'); + mkdirSync(path, { recursive: true }); + const entries = readdirSync(dirPath, { recursive: true, withFileTypes: true }); + expect(entries.find(e => e.name === 'directory').path).toBe(dirPath); + expect(entries.find(e => e.name === 'subdirectory').path).toBe(join(dirPath, 'directory')); + }); + }); + describe("recursive readdir async", () => { + it("should return the correct path values for directory and subdirectory", async () => { + const path = join(dirPath, 'directory', 'subdirectory'); + mkdirSync(path, { recursive: true }); + const entries = await promises.readdir(dirPath, { recursive: true, withFileTypes: true }); + expect(entries.find(e => e.name === 'directory').path).toBe(dirPath); + expect(entries.find(e => e.name === 'subdirectory').path).toBe(join(dirPath, 'directory')); + }); + }); +}); From 130237a04092c885df422988bf02570b03c7ab78 Mon Sep 17 00:00:00 2001 From: Nick Reilingh Date: Sun, 17 Dec 2023 22:21:14 -0500 Subject: [PATCH 12/13] Remove fake test file --- test/dirent.js | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 test/dirent.js diff --git a/test/dirent.js b/test/dirent.js deleted file mode 100644 index 4e333105c377ff..00000000000000 --- a/test/dirent.js +++ /dev/null @@ -1,38 +0,0 @@ -// This script tests the contents of fs.Dirent for all of the methods that return it. -// Compare running with node vs. running with Bun for compatibility. - -const fs = require('fs'); - -// From the working directory, create a collection of files and folders for testing. -const target = process.argv[2]; - -// pass arguments: -// /tmp/test -// ./test -// test -// . -// ../../test -// .. - -// path is always identical to the argument except for recursive entries -// For recursed entries, a leading `./` is not included - -fs.mkdirSync(target + '/subfolder/childfolder/grandchildfolder', { recursive: true }); -fs.writeFileSync(target + '/file.txt', 'test'); -fs.writeFileSync(target + '/subfolder/childfile.txt', 'test'); -fs.writeFileSync(target + '/subfolder/childfolder/grandchildfile.txt', 'test'); - -let results = {}; -function mapFiles(files) { - return files.map(f => ({ name: f.name, path: f.path, parentPath: f.parentPath })) - .toSorted((a, b) => a.path+'/'+a.name < b.path+'/'+b.name); -} - -results['fs.readdirSync'] = mapFiles(fs.readdirSync(target, { withFileTypes: true })); -results['fs.readdirSync recursive'] = mapFiles(fs.readdirSync(target, { withFileTypes: true, recursive: true })); -fs.promises.readdir(target, { withFileTypes: true, recursive: true }) - .then(files => { - results['fs.promises.readdir recursive'] = mapFiles(files); - console.log(results); - }); - From 7a490836de83a82f5cdc0e4c25447a6605c23a77 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 19:30:58 +0000 Subject: [PATCH 13/13] [autofix.ci] apply automated fixes --- test/js/node/fs/fs.test.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/js/node/fs/fs.test.ts b/test/js/node/fs/fs.test.ts index cd5da45329d0fa..e97a1194930b90 100644 --- a/test/js/node/fs/fs.test.ts +++ b/test/js/node/fs/fs.test.ts @@ -2492,36 +2492,36 @@ describe("Dirent name and path values", () => { }); describe("nonrecursive readdir", () => { it("should return the correct name and path values for directory", () => { - const path = join(dirPath, 'directory'); + const path = join(dirPath, "directory"); mkdirSync(path, { recursive: true }); const entries = readdirSync(dirPath, { withFileTypes: true }); - expect(entries[0].name).toBe('directory'); + expect(entries[0].name).toBe("directory"); expect(entries[0].path).toBe(dirPath); }); it("should return the correct name and path values for file", () => { - const path = join(dirPath, 'file.txt') - writeFileSync(path, 'Hello World'); + const path = join(dirPath, "file.txt"); + writeFileSync(path, "Hello World"); const entries = readdirSync(dirPath, { withFileTypes: true }); - expect(entries[0].name).toBe('file.txt'); + expect(entries[0].name).toBe("file.txt"); expect(entries[0].path).toBe(dirPath); }); }); describe("recursive readdirSync", () => { it("should return the correct path values for directory and subdirectory", () => { - const path = join(dirPath, 'directory', 'subdirectory'); + const path = join(dirPath, "directory", "subdirectory"); mkdirSync(path, { recursive: true }); const entries = readdirSync(dirPath, { recursive: true, withFileTypes: true }); - expect(entries.find(e => e.name === 'directory').path).toBe(dirPath); - expect(entries.find(e => e.name === 'subdirectory').path).toBe(join(dirPath, 'directory')); + expect(entries.find(e => e.name === "directory").path).toBe(dirPath); + expect(entries.find(e => e.name === "subdirectory").path).toBe(join(dirPath, "directory")); }); }); describe("recursive readdir async", () => { it("should return the correct path values for directory and subdirectory", async () => { - const path = join(dirPath, 'directory', 'subdirectory'); + const path = join(dirPath, "directory", "subdirectory"); mkdirSync(path, { recursive: true }); const entries = await promises.readdir(dirPath, { recursive: true, withFileTypes: true }); - expect(entries.find(e => e.name === 'directory').path).toBe(dirPath); - expect(entries.find(e => e.name === 'subdirectory').path).toBe(join(dirPath, 'directory')); + expect(entries.find(e => e.name === "directory").path).toBe(dirPath); + expect(entries.find(e => e.name === "subdirectory").path).toBe(join(dirPath, "directory")); }); }); });