1- import { test , expect } from "bun:test" ;
1+ import { expect , test } from "bun:test" ;
22import { bunEnv , bunExe , tempDirWithFiles } from "harness" ;
33
44test ( "circular dependencies should not cause infinite recursion during hoisting" , async ( ) => {
55 // This test reproduces a crash where circular dependencies in workspace packages
66 // would cause infinite recursion in the hoistDependency function, leading to
77 // stack overflow and segmentation fault.
8- //
8+ //
99 // The circular dependency pattern is: pkg-a -> pkg-b -> pkg-c -> pkg-a
10-
10+
1111 const dir = tempDirWithFiles ( "circular-deps" , {
1212 "package.json" : JSON . stringify ( {
1313 name : "root" ,
1414 dependencies : {
1515 "pkg-a" : "file:./pkg-a" ,
16- "pkg-b" : "file:./pkg-b" ,
17- "pkg-c" : "file:./pkg-c"
16+ "pkg-b" : "file:./pkg-b" ,
17+ "pkg-c" : "file:./pkg-c" ,
1818 } ,
1919 scripts : {
20- "o" : "bun outdated"
21- }
20+ "o" : "bun outdated" ,
21+ } ,
2222 } ) ,
2323 "pkg-a/package.json" : JSON . stringify ( {
2424 name : "pkg-a" ,
2525 dependencies : {
26- "pkg-b" : "file:../pkg-b"
27- }
26+ "pkg-b" : "file:../pkg-b" ,
27+ } ,
2828 } ) ,
2929 "pkg-b/package.json" : JSON . stringify ( {
30- name : "pkg-b" ,
30+ name : "pkg-b" ,
3131 dependencies : {
32- "pkg-c" : "file:../pkg-c"
33- }
32+ "pkg-c" : "file:../pkg-c" ,
33+ } ,
3434 } ) ,
3535 "pkg-c/package.json" : JSON . stringify ( {
3636 name : "pkg-c" ,
3737 dependencies : {
3838 "pkg-a" : "file:../pkg-a" ,
39- "react" : "^18.0.0"
40- }
39+ "react" : "^18.0.0" ,
40+ } ,
4141 } ) ,
4242 // Include a lockfile that reproduces the problematic state
43- "bun.lock" : JSON . stringify ( {
44- lockfileVersion : 1 ,
45- workspaces : {
46- "" : {
47- name : "root" ,
48- dependencies : {
49- "pkg-a" : "file:./pkg-a" ,
50- "pkg-b" : "file:./pkg-b" ,
51- "pkg-c" : "file:./pkg-c" ,
43+ "bun.lock" : JSON . stringify (
44+ {
45+ lockfileVersion : 1 ,
46+ workspaces : {
47+ "" : {
48+ name : "root" ,
49+ dependencies : {
50+ "pkg-a" : "file:./pkg-a" ,
51+ "pkg-b" : "file:./pkg-b" ,
52+ "pkg-c" : "file:./pkg-c" ,
53+ } ,
5254 } ,
5355 } ,
56+ packages : {
57+ "js-tokens" : [
58+ 59+ "" ,
60+ { } ,
61+ "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" ,
62+ ] ,
63+ "loose-envify" : [
64+ 65+ "" ,
66+ { "dependencies" : { "js-tokens" : "^3.0.0 || ^4.0.0" } , "bin" : { "loose-envify" : "cli.js" } } ,
67+ "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==" ,
68+ ] ,
69+ "pkg-a" : [ "pkg-a@file:pkg-a" , { "dependencies" : { "pkg-b" : "file:../pkg-b" } } ] ,
70+ "pkg-b" : [ "pkg-b@file:pkg-b" , { "dependencies" : { "pkg-c" : "file:../pkg-c" } } ] ,
71+ "pkg-c" : [ "pkg-c@file:pkg-c" , { "dependencies" : { "pkg-a" : "file:../pkg-a" , "react" : "^18.0.0" } } ] ,
72+ "react" : [
73+ 74+ "" ,
75+ { "dependencies" : { "loose-envify" : "^1.1.0" } } ,
76+ "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==" ,
77+ ] ,
78+ "pkg-a/pkg-b" : [ "pkg-b@file:pkg-b" , { } ] ,
79+ "pkg-b/pkg-c" : [ "pkg-c@file:pkg-c" , { } ] ,
80+ "pkg-c/pkg-a" : [ "pkg-a@file:pkg-a" , { } ] ,
81+ } ,
5482 } ,
55- packages : {
56- "js-tokens" :
[ "[email protected] " , "" , { } , "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" ] , 57- "loose-envify" :
[ "[email protected] " , "" , { "dependencies" :
{ "js-tokens" :
"^3.0.0 || ^4.0.0" } , "bin" :
{ "loose-envify" :
"cli.js" } } , "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==" ] , 58- "pkg-a" : [ "pkg-a@file:pkg-a" , { "dependencies" : { "pkg-b" : "file:../pkg-b" } } ] ,
59- "pkg-b" : [ "pkg-b@file:pkg-b" , { "dependencies" : { "pkg-c" : "file:../pkg-c" } } ] ,
60- "pkg-c" : [ "pkg-c@file:pkg-c" , { "dependencies" : { "pkg-a" : "file:../pkg-a" , "react" : "^18.0.0" } } ] ,
61- "react" :
[ "[email protected] " , "" , { "dependencies" :
{ "loose-envify" :
"^1.1.0" } } , "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==" ] , 62- "pkg-a/pkg-b" : [ "pkg-b@file:pkg-b" , { } ] ,
63- "pkg-b/pkg-c" : [ "pkg-c@file:pkg-c" , { } ] ,
64- "pkg-c/pkg-a" : [ "pkg-a@file:pkg-a" , { } ] ,
65- }
66- } , null , 2 )
83+ null ,
84+ 2 ,
85+ ) ,
6786 } ) ;
6887
6988 // Run bun install - this should complete without crashing
@@ -75,15 +94,11 @@ test("circular dependencies should not cause infinite recursion during hoisting"
7594 stdout : "pipe" ,
7695 } ) ;
7796
78- const [ stdout , stderr , exitCode ] = await Promise . all ( [
79- proc . stdout . text ( ) ,
80- proc . stderr . text ( ) ,
81- proc . exited ,
82- ] ) ;
97+ const [ stdout , stderr , exitCode ] = await Promise . all ( [ proc . stdout . text ( ) , proc . stderr . text ( ) , proc . exited ] ) ;
8398
8499 // Should exit successfully, not crash with segmentation fault
85100 expect ( exitCode ) . toBe ( 0 ) ;
86101 expect ( stderr ) . not . toContain ( "panic" ) ;
87- expect ( stderr ) . not . toContain ( "Segmentation fault" ) ;
102+ expect ( stderr ) . not . toContain ( "Segmentation fault" ) ;
88103 expect ( stdout ) . toContain ( "packages installed" ) ;
89- } , 30000 ) ; // 30 second timeout
104+ } , 30000 ) ; // 30 second timeout
0 commit comments