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.
This commit is contained in:
Nico Cevallos
2025-12-26 04:49:23 -03:00
committed by GitHub
parent 28fd495b39
commit 5715b54614
4 changed files with 49 additions and 10 deletions

View File

@@ -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| {

View File

@@ -828,9 +828,10 @@ function rejects(
error: nodeAssert.AssertPredicate,
message?: string | Error,
): Promise<void>;
assert.rejects = async function rejects(promiseFn: () => Promise<unknown>, ...args: any[]): Promise<void> {
expectsError(rejects, await waitForActual(promiseFn), ...args);
};
async function rejects(block: (() => Promise<unknown>) | Promise<unknown>, ...args: any[]): Promise<void> {
expectsError(rejects, await waitForActual(block), ...args);
}
assert.rejects = rejects;
/**
* Asserts that the function `fn` does not throw an error.

View File

@@ -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);

View File

@@ -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: {