From 5715b54614cbdb885ab42584d401c300cdff9519 Mon Sep 17 00:00:00 2001 From: Nico Cevallos Date: Fri, 26 Dec 2025 04:49:23 -0300 Subject: [PATCH] add test for dependency order when a package's name is larger than 8 characters + fix (#25697) ### What does this PR do? - Add test that is broken before the changes in the code and fix previous test making script in dependency takes a bit of time to be executed. Without the `setTimeout` in the tests, due race conditions it always success. I tried adding a test combining both tests, with dependencies `dep0` and `larger-than-8-char`, but if the timeout is the same it success. - Fix for the use case added, by using the correct buffer for `Dependency.name` otherwise it gets garbage when package name is larger than 8 characters. This should fix #12203 ### How did you verify your code works? Undo the changes in the code to verify the new test fails and check it again after adding the changes in the code. --- src/cli/filter_run.zig | 7 ++--- src/js/node/assert.ts | 7 +++-- src/resolver/package_json.zig | 2 +- test/cli/run/filter-workspace.test.ts | 43 ++++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/cli/filter_run.zig b/src/cli/filter_run.zig index 334432a281..1a4fee2d1f 100644 --- a/src/cli/filter_run.zig +++ b/src/cli/filter_run.zig @@ -584,13 +584,10 @@ pub fn runScriptsWithFilter(ctx: Command.Context) !noreturn { } // compute dependencies (TODO: maybe we should do this only in a workspace?) for (state.handles) |*handle| { + const source_buf = handle.config.deps.source_buf; var iter = handle.config.deps.map.iterator(); while (iter.next()) |entry| { - var sfa = std.heap.stackFallback(256, ctx.allocator); - const alloc = sfa.get(); - const buf = try alloc.alloc(u8, entry.key_ptr.len()); - defer alloc.free(buf); - const name = entry.key_ptr.slice(buf); + const name = entry.key_ptr.slice(source_buf); // is it a workspace dependency? if (map.get(name)) |pkgs| { for (pkgs.items) |dep| { diff --git a/src/js/node/assert.ts b/src/js/node/assert.ts index 454b2b3b0d..0507b5c620 100644 --- a/src/js/node/assert.ts +++ b/src/js/node/assert.ts @@ -828,9 +828,10 @@ function rejects( error: nodeAssert.AssertPredicate, message?: string | Error, ): Promise; -assert.rejects = async function rejects(promiseFn: () => Promise, ...args: any[]): Promise { - expectsError(rejects, await waitForActual(promiseFn), ...args); -}; +async function rejects(block: (() => Promise) | Promise, ...args: any[]): Promise { + expectsError(rejects, await waitForActual(block), ...args); +} +assert.rejects = rejects; /** * Asserts that the function `fn` does not throw an error. diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig index 1ccf7529ca..380ceb4fbf 100644 --- a/src/resolver/package_json.zig +++ b/src/resolver/package_json.zig @@ -1031,7 +1031,7 @@ pub const PackageJSON = struct { const name_prop = prop.key orelse continue; const name_str = name_prop.asString(allocator) orelse continue; const name_hash = String.Builder.stringHash(name_str); - const name = String.init(name_str, name_str); + const name = String.init(package_json.dependencies.source_buf, name_str); const version_value = prop.value orelse continue; const version_str = version_value.asString(allocator) orelse continue; const sliced_str = Semver.SlicedString.init(version_str, version_str); diff --git a/test/cli/run/filter-workspace.test.ts b/test/cli/run/filter-workspace.test.ts index 8a6b064a77..42bd082cf7 100644 --- a/test/cli/run/filter-workspace.test.ts +++ b/test/cli/run/filter-workspace.test.ts @@ -275,7 +275,10 @@ describe("bun", () => { test("respect dependency order", () => { const dir = tempDirWithFiles("testworkspace", { dep0: { - "index.js": "Bun.write('out.txt', 'success')", + "index.js": [ + "await new Promise((resolve) => setTimeout(resolve, 100))", + "Bun.write('out.txt', 'success')", + ].join(";"), "package.json": JSON.stringify({ name: "dep0", scripts: { @@ -305,6 +308,44 @@ describe("bun", () => { }); }); + test("respect dependency order when dependency name is larger than 8 characters", () => { + const largeNamePkgName = "larger-than-8-char"; + const fileContent = `${largeNamePkgName} - ${new Date().getTime()}`; + const largeNamePkg = { + "index.js": [ + "await new Promise((resolve) => setTimeout(resolve, 100))", + `Bun.write('out.txt', '${fileContent}')`, + ].join(";"), + "package.json": JSON.stringify({ + name: largeNamePkgName, + scripts: { + script: `${bunExe()} run index.js`, + }, + }), + }; + const dir = tempDirWithFiles("testworkspace", { + main: { + "index.js": `console.log(await Bun.file("../${largeNamePkgName}/out.txt").text())`, + "package.json": JSON.stringify({ + name: "main", + dependencies: { + [largeNamePkgName]: "*", + }, + scripts: { + script: `${bunExe()} run index.js`, + }, + }), + }, + [largeNamePkgName]: largeNamePkg, + }); + runInCwdSuccess({ + cwd: dir, + pattern: "*", + target_pattern: [new RegExp(fileContent)], + command: ["script"], + }); + }); + test("ignore dependency order on cycle, preserving pre and post script order", () => { const dir = tempDirWithFiles("testworkspace", { dep0: {