Skip to content

Commit

Permalink
fix remaining node-module-module tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dylan-conway committed Feb 2, 2024
1 parent a2c9f6b commit a8feb4e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 23 deletions.
3 changes: 3 additions & 0 deletions src/bun.js/bindings/CommonJSModuleRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ JSC_DEFINE_HOST_FUNCTION(functionCommonJSModuleRecord_compile, (JSGlobalObject *
moduleObject->sourceCode.set(vm, moduleObject, jsSourceCode);

auto index = filenameString.reverseFind(PLATFORM_SEP, filenameString.length());
// filenameString is coming from js, any separator could be used
if (index == WTF::notFound)
index = filenameString.reverseFind(NOT_PLATFORM_SEP, filenameString.length());
String dirnameString;
if (index != WTF::notFound) {
dirnameString = filenameString.substring(0, index);
Expand Down
4 changes: 4 additions & 0 deletions src/bun.js/bindings/PathInlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
#if OS(WINDOWS)
#define PLATFORM_SEP_s "\\"_s
#define PLATFORM_SEP '\\'
#define NOT_PLATFORM_SEP_s "/"_s
#define NOT_PLATFORM_SEP '/'
#else
#define PLATFORM_SEP_s "/"_s
#define PLATFORM_SEP '/'
#define NOT_PLATFORM_SEP_s "\\"_s
#define NOT_PLATFORM_SEP '\\'
#endif

ALWAYS_INLINE bool isAbsolutePath(WTF::String input)
Expand Down
26 changes: 19 additions & 7 deletions src/resolver/resolve_path.zig
Original file line number Diff line number Diff line change
Expand Up @@ -578,15 +578,27 @@ pub fn windowsFilesystemRoot(path: []const u8) []const u8 {
return windowsFilesystemRootT(u8, path);
}

pub fn isDriveLetter(c: u8) bool {
return isDriveLetterT(u8, c);
}

pub fn isDriveLetterT(comptime T: type, c: T) bool {
return 'a' <= c and c <= 'z' or 'A' <= c and c <= 'Z';
}

// path.relative lets you do relative across different share drives
pub fn windowsFilesystemRootT(comptime T: type, path: []const T) []const T {
if (path.len < 3)
// minimum: `C:`
if (path.len < 2)
return if (isSepAnyT(T, path[0])) path[0..1] else path[0..0];
// with drive letter
const c = path[0];
if (path[1] == ':' and isSepAnyT(T, path[2])) {
if ('a' <= c and c <= 'z' or 'A' <= c and c <= 'Z') {
return path[0..3];
if (path[1] == ':') {
if (isDriveLetterT(T, c)) {
if (path.len > 2 and isSepAnyT(T, path[2]))
return path[0..3]
else
return path[0..2];
}
}
// UNC
Expand Down Expand Up @@ -759,7 +771,7 @@ pub fn normalizeStringGenericT(

if (preserve_trailing_slash) {
// Was there a trailing slash? Let's keep it.
if (buf_i > 0 and path_[path_.len - 1] == separator and buf[buf_i] != separator) {
if (buf_i > 0 and path_[path_.len - 1] == separator and buf[buf_i - 1] != separator) {
buf[buf_i] = separator;
buf_i += 1;
}
Expand Down Expand Up @@ -1004,7 +1016,7 @@ pub fn normalizeStringBuf(
buf: []u8,
comptime allow_above_root: bool,
comptime _platform: Platform,
comptime preserve_trailing_slash: anytype,
comptime preserve_trailing_slash: bool,
) []u8 {
return normalizeStringBufT(u8, str, buf, allow_above_root, _platform, preserve_trailing_slash);
}
Expand All @@ -1015,7 +1027,7 @@ pub fn normalizeStringBufT(
buf: []T,
comptime allow_above_root: bool,
comptime _platform: Platform,
comptime preserve_trailing_slash: anytype,
comptime preserve_trailing_slash: bool,
) []T {
const platform = comptime _platform.resolve();

Expand Down
22 changes: 16 additions & 6 deletions src/resolver/resolver.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3277,7 +3277,17 @@ pub const Resolver = struct {
defer sliced.deinit();

const str = brk: {
if (std.fs.path.isAbsolute(sliced.slice())) break :brk sliced.slice();
if (std.fs.path.isAbsolute(sliced.slice())) {
if (comptime Environment.isWindows) {
const dir_path_buf = bufs(.node_modules_paths_buf);
var normalizer = bun.path.PosixToWinNormalizer{};
const normalized = normalizer.resolveCWD(sliced.slice()) catch {
@panic("Failed to get cwd for _nodeModulesPaths");
};
break :brk bun.path.normalizeBuf(normalized, dir_path_buf, .windows);
}
break :brk sliced.slice();
}
const dir_path_buf = bufs(.node_modules_paths_buf);
break :brk bun.path.joinStringBuf(dir_path_buf, &[_]string{ r.fs.top_level_dir, sliced.slice() }, .auto);
};
Expand All @@ -3292,10 +3302,10 @@ pub const Resolver = struct {
const path_without_trailing_slash = strings.withoutTrailingSlash(dir_info.abs_path);
const path_parts = brk: {
if (path_without_trailing_slash.len == 1 and path_without_trailing_slash[0] == '/') {
break :brk [2]string{ "", "/node_modules" };
break :brk [2]string{ "", std.fs.path.sep_str ++ "node_modules" };
}

break :brk [2]string{ path_without_trailing_slash, "/node_modules" };
break :brk [2]string{ path_without_trailing_slash, std.fs.path.sep_str ++ "node_modules" };
};
const nodemodules_path = bun.strings.concat(stack_fallback_allocator.get(), &path_parts) catch unreachable;
bun.path.posixToPlatformInPlace(u8, nodemodules_path);
Expand All @@ -3305,7 +3315,7 @@ pub const Resolver = struct {
} else {
// does not exist
const full_path = std.fs.path.resolve(r.allocator, &[1][]const u8{str}) catch unreachable;
var path = full_path;
var path = strings.withoutTrailingSlash(full_path);
while (true) {
const path_without_trailing_slash = strings.withoutTrailingSlash(path);

Expand All @@ -3315,13 +3325,13 @@ pub const Resolver = struct {
stack_fallback_allocator.get(),
&[_]string{
path_without_trailing_slash,
"/node_modules",
std.fs.path.sep_str ++ "node_modules",
},
) catch unreachable,
),
) catch unreachable;

path = path[0 .. strings.lastIndexOfChar(path, '/') orelse break];
path = path[0 .. strings.lastIndexOfChar(path, std.fs.path.sep) orelse break];
}
}

Expand Down
24 changes: 14 additions & 10 deletions test/js/node/module/node-module-module.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @known-failing-on-windows: 1 failing
import { expect, test } from "bun:test";
import { bunEnv, bunExe } from "harness";
import { bunEnv, bunExe, ospath } from "harness";
import { _nodeModulePaths, builtinModules, isBuiltin, wrap } from "module";
import Module from "module";
import path from "path";
Expand Down Expand Up @@ -37,21 +36,26 @@ test("module.Module works", () => {
});

test("_nodeModulePaths() works", () => {
const root = process.platform === "win32" ? "C:\\" : "/";
expect(() => {
_nodeModulePaths();
}).toThrow();
expect(_nodeModulePaths(".").length).toBeGreaterThan(0);
expect(_nodeModulePaths(".").pop()).toBe("/node_modules");
expect(_nodeModulePaths(".").pop()).toBe(root + "node_modules");
expect(_nodeModulePaths("")).toEqual(_nodeModulePaths("."));
expect(_nodeModulePaths("/")).toEqual(["/node_modules"]);
expect(_nodeModulePaths("/")).toEqual([root + "node_modules"]);
expect(_nodeModulePaths("/a/b/c/d")).toEqual([
"/a/b/c/d/node_modules",
"/a/b/c/node_modules",
"/a/b/node_modules",
"/a/node_modules",
"/node_modules",
ospath(root + "a/b/c/d/node_modules"),
ospath(root + "a/b/c/node_modules"),
ospath(root + "a/b/node_modules"),
ospath(root + "a/node_modules"),
ospath(root + "node_modules"),
]);
expect(_nodeModulePaths("/a/b/../d")).toEqual([
ospath(root + "a/d/node_modules"),
ospath(root + "a/node_modules"),
ospath(root + "node_modules"),
]);
expect(_nodeModulePaths("/a/b/../d")).toEqual(["/a/d/node_modules", "/a/node_modules", "/node_modules"]);
});

test("Module.wrap", () => {
Expand Down

0 comments on commit a8feb4e

Please sign in to comment.