diff options
author | 2022-02-04 02:05:41 -0800 | |
---|---|---|
committer | 2022-02-04 02:05:41 -0800 | |
commit | 909e6a6bab01661c1e015658987ba6f53ee3ffd2 (patch) | |
tree | 08c49af3fa689db630093e898cb808943b844cef | |
parent | a2f91b167d6a58c26454cd29a051084d4ea47c7c (diff) | |
download | bun-909e6a6bab01661c1e015658987ba6f53ee3ffd2.tar.gz bun-909e6a6bab01661c1e015658987ba6f53ee3ffd2.tar.zst bun-909e6a6bab01661c1e015658987ba6f53ee3ffd2.zip |
`path.resolve()` passes tests
-rw-r--r-- | integration/bunjs-only-snippets/path.test.js | 65 | ||||
-rw-r--r-- | src/javascript/jsc/node/types.zig | 29 |
2 files changed, 81 insertions, 13 deletions
diff --git a/integration/bunjs-only-snippets/path.test.js b/integration/bunjs-only-snippets/path.test.js index d6987bf80..997368150 100644 --- a/integration/bunjs-only-snippets/path.test.js +++ b/integration/bunjs-only-snippets/path.test.js @@ -390,3 +390,68 @@ it("path.normalize", () => { ); strictEqual(path.posix.normalize("foo/bar\\baz"), "foo/bar\\baz"); }); + +it("path.resolve", () => { + const failures = []; + const slashRE = /\//g; + const backslashRE = /\\/g; + + const resolveTests = [ + // [ + // path.win32.resolve, + // // Arguments result + // [ + // [["c:/blah\\blah", "d:/games", "c:../a"], "c:\\blah\\a"], + // [["c:/ignore", "d:\\a/b\\c/d", "\\e.exe"], "d:\\e.exe"], + // [["c:/ignore", "c:/some/file"], "c:\\some\\file"], + // [["d:/ignore", "d:some/dir//"], "d:\\ignore\\some\\dir"], + // [["."], process.cwd()], + // [["//server/share", "..", "relative\\"], "\\\\server\\share\\relative"], + // [["c:/", "//"], "c:\\"], + // [["c:/", "//dir"], "c:\\dir"], + // [["c:/", "//server/share"], "\\\\server\\share\\"], + // [["c:/", "//server//share"], "\\\\server\\share\\"], + // [["c:/", "///some//dir"], "c:\\some\\dir"], + // [ + // ["C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js"], + // "C:\\foo\\tmp.3\\cycles\\root.js", + // ], + // ], + // ], + [ + path.posix.resolve, + // Arguments result + [ + [["/var/lib", "../", "file/"], "/var/file"], + [["/var/lib", "/../", "file/"], "/file"], + [["a/b/c/", "../../.."], process.cwd()], + [["."], process.cwd()], + [["/some/dir", ".", "/absolute/"], "/absolute"], + [ + ["/foo/tmp.3/", "../tmp.3/cycles/root.js"], + "/foo/tmp.3/cycles/root.js", + ], + ], + ], + ]; + const isWindows = false; + resolveTests.forEach(([resolve, tests]) => { + tests.forEach(([test, expected]) => { + const actual = resolve.apply(null, test); + let actualAlt; + const os = resolve === path.win32.resolve ? "win32" : "posix"; + if (resolve === path.win32.resolve && !isWindows) + actualAlt = actual.replace(backslashRE, "/"); + else if (resolve !== path.win32.resolve && isWindows) + actualAlt = actual.replace(slashRE, "\\"); + + const message = `path.${os}.resolve(${test + .map(JSON.stringify) + .join(",")})\n expect=${JSON.stringify( + expected + )}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected && actualAlt !== expected) failures.push(message); + }); + }); + strictEqual(failures.length, 0, failures.join("\n")); +}); diff --git a/src/javascript/jsc/node/types.zig b/src/javascript/jsc/node/types.zig index 005ba6860..b02d5ef89 100644 --- a/src/javascript/jsc/node/types.zig +++ b/src/javascript/jsc/node/types.zig @@ -2136,17 +2136,17 @@ pub const Path = struct { return JSC.ZigString.init(out).withEncoding().toValueGC(globalThis); } } + fn isAbsoluteString(path: JSC.ZigString, windows: bool) bool { + if (!windows) return path.len > 0 and path.slice()[0] == '/'; + + return isZigStringAbsoluteWindows(path); + } pub fn isAbsolute(globalThis: *JSC.JSGlobalObject, isWindows: bool, args_ptr: [*]JSC.JSValue, args_len: u16) callconv(.C) JSC.JSValue { if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); if (args_len == 0) return JSC.JSValue.jsBoolean(false); var zig_str: JSC.ZigString = args_ptr[0].getZigString(globalThis); if (zig_str.isEmpty()) return JSC.JSValue.jsBoolean(false); - - if (!isWindows) { - return JSC.JSValue.jsBoolean(zig_str.slice()[0] == '/'); - } - - return JSC.JSValue.jsBoolean(isZigStringAbsoluteWindows(zig_str)); + return JSC.JSValue.jsBoolean(isAbsoluteString(zig_str, isWindows)); } fn isZigStringAbsoluteWindows(zig_str: JSC.ZigString) bool { if (zig_str.is16Bit()) { @@ -2298,28 +2298,31 @@ pub const Path = struct { pub fn resolve(globalThis: *JSC.JSGlobalObject, isWindows: bool, args_ptr: [*]JSC.JSValue, args_len: u16) callconv(.C) JSC.JSValue { if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - if (args_len < 2) return normalize(globalThis, isWindows, args_ptr, args_len); var stack_fallback_allocator = std.heap.stackFallback( (32 * @sizeOf(string)), heap_allocator, ); var allocator = stack_fallback_allocator.get(); - var out_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - // TODO: - _ = isWindows; + var out_buf: [std.fs.MAX_PATH_BYTES * 2]u8 = undefined; + var parts = allocator.alloc(string, args_len) catch unreachable; defer allocator.free(parts); - var i: u16 = 0; + var arena = std.heap.ArenaAllocator.init(heap_allocator); var arena_allocator = arena.allocator(); defer arena.deinit(); + var i: u16 = 0; while (i < args_len) : (i += 1) { - parts[i] = args_ptr[0].toSlice(globalThis, arena_allocator).slice(); + parts[i] = args_ptr[i].toSlice(globalThis, arena_allocator).slice(); } - var out = JSC.ZigString.init(PathHandler.joinAbsStringBuf(Fs.FileSystem.instance.top_level_dir, &out_buf, parts, .posix)); + var out = if (!isWindows) + JSC.ZigString.init(PathHandler.joinAbsStringBuf(Fs.FileSystem.instance.top_level_dir, &out_buf, parts, .posix)) + else + JSC.ZigString.init(PathHandler.joinAbsStringBuf(Fs.FileSystem.instance.top_level_dir, &out_buf, parts, .windows)); + if (arena.state.buffer_list.first != null) out.setOutputEncoding(); return out.toValueGC(globalThis); } |