@@ -4135,3 +4135,258 @@ t.test('engine checking respects omit flags', async t => {
4135
4135
t . pass ( 'should succeed when omitting peer dependencies with engine mismatches' )
4136
4136
} )
4137
4137
} )
4138
+
4139
+ t . test ( 'installLinks behavior with project-internal file dependencies' , async t => {
4140
+ t . test ( 'project-internal file dependencies are always symlinked regardless of installLinks' , async t => {
4141
+ const path = t . testdir ( {
4142
+ 'package.json' : JSON . stringify ( {
4143
+ name : 'test-root' ,
4144
+ version : '1.0.0' ,
4145
+ dependencies : {
4146
+ 'local-pkg' : 'file:./packages/local-pkg' ,
4147
+ } ,
4148
+ } ) ,
4149
+ packages : {
4150
+ 'local-pkg' : {
4151
+ 'package.json' : JSON . stringify ( {
4152
+ name : 'local-pkg' ,
4153
+ version : '1.0.0' ,
4154
+ dependencies : {
4155
+ 'local-shared' : 'file:../local-shared' , // Project-internal dependency
4156
+ } ,
4157
+ } ) ,
4158
+ 'index.js' : 'module.exports = "local-pkg"' ,
4159
+ } ,
4160
+ 'local-shared' : {
4161
+ 'package.json' : JSON . stringify ( {
4162
+ name : 'local-shared' ,
4163
+ version : '1.0.0' ,
4164
+ } ) ,
4165
+ 'index.js' : 'module.exports = "local-shared"' ,
4166
+ } ,
4167
+ } ,
4168
+ } )
4169
+
4170
+ createRegistry ( t , false )
4171
+
4172
+ // Test with installLinks=true (this used to fail before our fix)
4173
+ const arb = newArb ( path , { installLinks : true } )
4174
+ const tree = await arb . buildIdealTree ( )
4175
+
4176
+ // Both packages should be present in the tree
4177
+ t . ok ( tree . children . has ( 'local-pkg' ) , 'local-pkg should be in the tree' )
4178
+ t . ok ( tree . children . has ( 'local-shared' ) , 'local-shared should be in the tree' )
4179
+
4180
+ // Both should be Links (symlinked) because they are project-internal
4181
+ const localPkg = tree . children . get ( 'local-pkg' )
4182
+ const localShared = tree . children . get ( 'local-shared' )
4183
+
4184
+ t . ok ( localPkg . isLink , 'local-pkg should be a link' )
4185
+ t . ok ( localShared . isLink , 'local-shared should be a link (hoisted from local-pkg)' )
4186
+
4187
+ // Verify the paths are correct
4188
+ t . ok ( localPkg . realpath . endsWith ( join ( 'packages' , 'local-pkg' ) ) , 'local-pkg should link to correct path' )
4189
+ t . ok ( localShared . realpath . endsWith ( join ( 'packages' , 'local-shared' ) ) , 'local-shared should link to correct path' )
4190
+ } )
4191
+
4192
+ t . test ( 'external file dependencies respect installLinks setting' , async t => {
4193
+ // Create test structure with both project and external dependency in same testdir
4194
+ const testRoot = t . testdir ( {
4195
+ project : {
4196
+ 'package.json' : JSON . stringify ( {
4197
+ name : 'test-project' ,
4198
+ version : '1.0.0' ,
4199
+ dependencies : {
4200
+ 'external-lib' : 'file:../external-lib' , // External dependency (outside project)
4201
+ } ,
4202
+ } ) ,
4203
+ } ,
4204
+ 'external-lib' : {
4205
+ 'package.json' : JSON . stringify ( {
4206
+ name : 'external-lib' ,
4207
+ version : '1.0.0' ,
4208
+ } ) ,
4209
+ 'index.js' : 'module.exports = "external-lib"' ,
4210
+ } ,
4211
+ } )
4212
+
4213
+ const projectPath = join ( testRoot , 'project' )
4214
+ createRegistry ( t , false )
4215
+
4216
+ // Test with installLinks=true - external dependency should be copied (not linked)
4217
+ const arbWithLinks = newArb ( projectPath , { installLinks : true } )
4218
+ const treeWithLinks = await arbWithLinks . buildIdealTree ( )
4219
+
4220
+ t . ok ( treeWithLinks . children . has ( 'external-lib' ) , 'external-lib should be in the tree' )
4221
+ const externalWithLinks = treeWithLinks . children . get ( 'external-lib' )
4222
+ t . notOk ( externalWithLinks . isLink , 'external-lib should not be a link when installLinks=true' )
4223
+
4224
+ // Test with installLinks=false - external dependency should be linked
4225
+ const arbNoLinks = newArb ( projectPath , { installLinks : false } )
4226
+ const treeNoLinks = await arbNoLinks . buildIdealTree ( )
4227
+
4228
+ t . ok ( treeNoLinks . children . has ( 'external-lib' ) , 'external-lib should be in the tree' )
4229
+ const externalNoLinks = treeNoLinks . children . get ( 'external-lib' )
4230
+ t . ok ( externalNoLinks . isLink , 'external-lib should be a link when installLinks=false' )
4231
+ } )
4232
+
4233
+ t . test ( 'mixed internal and external file dependencies' , async t => {
4234
+ const testRoot = t . testdir ( {
4235
+ project : {
4236
+ 'package.json' : JSON . stringify ( {
4237
+ name : 'mixed-test' ,
4238
+ version : '1.0.0' ,
4239
+ dependencies : {
4240
+ 'internal-pkg' : 'file:./lib/internal-pkg' ,
4241
+ 'external-dep' : 'file:../external-dep' , // External dependency
4242
+ } ,
4243
+ } ) ,
4244
+ lib : {
4245
+ 'internal-pkg' : {
4246
+ 'package.json' : JSON . stringify ( {
4247
+ name : 'internal-pkg' ,
4248
+ version : '1.0.0' ,
4249
+ dependencies : {
4250
+ 'internal-shared' : 'file:../internal-shared' , // Project-internal
4251
+ } ,
4252
+ } ) ,
4253
+ 'index.js' : 'module.exports = "internal-pkg"' ,
4254
+ } ,
4255
+ 'internal-shared' : {
4256
+ 'package.json' : JSON . stringify ( {
4257
+ name : 'internal-shared' ,
4258
+ version : '1.0.0' ,
4259
+ } ) ,
4260
+ 'index.js' : 'module.exports = "internal-shared"' ,
4261
+ } ,
4262
+ } ,
4263
+ } ,
4264
+ 'external-dep' : {
4265
+ 'package.json' : JSON . stringify ( {
4266
+ name : 'external-dep' ,
4267
+ version : '1.0.0' ,
4268
+ } ) ,
4269
+ 'index.js' : 'module.exports = "external-dep"' ,
4270
+ } ,
4271
+ } )
4272
+
4273
+ const projectPath = join ( testRoot , 'project' )
4274
+ createRegistry ( t , false )
4275
+
4276
+ const arb = newArb ( projectPath , { installLinks : true } )
4277
+ const tree = await arb . buildIdealTree ( )
4278
+
4279
+ // All dependencies should be present
4280
+ t . ok ( tree . children . has ( 'internal-pkg' ) , 'internal-pkg should be in tree' )
4281
+ t . ok ( tree . children . has ( 'internal-shared' ) , 'internal-shared should be in tree' )
4282
+ t . ok ( tree . children . has ( 'external-dep' ) , 'external-dep should be in tree' )
4283
+
4284
+ // Internal dependencies should be links (project-internal rule)
4285
+ const internalPkg = tree . children . get ( 'internal-pkg' )
4286
+ const internalShared = tree . children . get ( 'internal-shared' )
4287
+ t . ok ( internalPkg . isLink , 'internal-pkg should be a link (project-internal)' )
4288
+ t . ok ( internalShared . isLink , 'internal-shared should be a link (project-internal)' )
4289
+
4290
+ // External dependency should not be a link (respects installLinks=true)
4291
+ const externalDep = tree . children . get ( 'external-dep' )
4292
+ t . notOk ( externalDep . isLink , 'external-dep should not be a link (respects installLinks=true)' )
4293
+ } )
4294
+
4295
+ t . test ( 'code coverage for project-internal file dependency edge cases' , async t => {
4296
+ const testRoot = t . testdir ( {
4297
+ 'parent-dir-external' : {
4298
+ 'package.json' : JSON . stringify ( {
4299
+ name : 'parent-dir-external' ,
4300
+ version : '1.0.0' ,
4301
+ } ) ,
4302
+ 'index.js' : 'module.exports = "parent-dir-external"' ,
4303
+ } ,
4304
+ project : {
4305
+ 'package.json' : JSON . stringify ( {
4306
+ name : 'coverage-test' ,
4307
+ version : '1.0.0' ,
4308
+ dependencies : {
4309
+ 'current-dir-dep' : 'file:./current-dir-dep' , // file:./ case
4310
+ 'parent-dir-external' : 'file:../parent-dir-external' , // file:../ case outside project
4311
+ } ,
4312
+ } ) ,
4313
+ 'current-dir-dep' : {
4314
+ 'package.json' : JSON . stringify ( {
4315
+ name : 'current-dir-dep' ,
4316
+ version : '1.0.0' ,
4317
+ } ) ,
4318
+ 'index.js' : 'module.exports = "current-dir-dep"' ,
4319
+ } ,
4320
+ } ,
4321
+ } )
4322
+
4323
+ const projectPath = join ( testRoot , 'project' )
4324
+ createRegistry ( t , false )
4325
+
4326
+ // Test with installLinks=false to verify external dependencies respect setting
4327
+ const arb = newArb ( projectPath , { installLinks : false } )
4328
+ const tree = await arb . buildIdealTree ( )
4329
+
4330
+ t . ok ( tree . children . has ( 'current-dir-dep' ) , 'current-dir-dep should be in tree' )
4331
+ t . ok ( tree . children . has ( 'parent-dir-external' ) , 'parent-dir-external should be in tree' )
4332
+
4333
+ const currentDirDep = tree . children . get ( 'current-dir-dep' )
4334
+ const parentDirExternal = tree . children . get ( 'parent-dir-external' )
4335
+
4336
+ // current-dir-dep should be a link (project-internal always links)
4337
+ t . ok ( currentDirDep . isLink , 'current-dir-dep should be a link (file:./ within project)' )
4338
+
4339
+ // parent-dir-external should ALSO be a link (external, but installLinks=false means link everything)
4340
+ t . ok ( parentDirExternal . isLink , 'parent-dir-external should be a link (file:../ outside project, installLinks=false means link)' )
4341
+
4342
+ // Verify the logic branches - current-dir should resolve within project, parent-dir should not
4343
+ t . match ( currentDirDep . realpath , new RegExp ( join ( testRoot , 'project' ) . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ) ,
4344
+ 'current-dir-dep realpath should be within project root' )
4345
+ } )
4346
+
4347
+ t . test ( 'installLinks=true with nested project-internal file dependencies' , async t => {
4348
+ // Test a more complex scenario with nested dependencies to ensure comprehensive coverage
4349
+ const testRoot = t . testdir ( {
4350
+ project : {
4351
+ 'package.json' : JSON . stringify ( {
4352
+ name : 'nested-test' ,
4353
+ version : '1.0.0' ,
4354
+ dependencies : {
4355
+ 'wrapper-pkg' : 'file:./packages/wrapper-pkg' ,
4356
+ } ,
4357
+ } ) ,
4358
+ packages : {
4359
+ 'wrapper-pkg' : {
4360
+ 'package.json' : JSON . stringify ( {
4361
+ name : 'wrapper-pkg' ,
4362
+ version : '1.0.0' ,
4363
+ dependencies : {
4364
+ 'nested-dep' : 'file:../nested-dep' ,
4365
+ } ,
4366
+ } ) ,
4367
+ } ,
4368
+ 'nested-dep' : {
4369
+ 'package.json' : JSON . stringify ( {
4370
+ name : 'nested-dep' ,
4371
+ version : '1.0.0' ,
4372
+ } ) ,
4373
+ } ,
4374
+ } ,
4375
+ } ,
4376
+ } )
4377
+
4378
+ const projectPath = join ( testRoot , 'project' )
4379
+ createRegistry ( t , false )
4380
+
4381
+ const arb = newArb ( projectPath , { installLinks : true } )
4382
+ const tree = await arb . buildIdealTree ( )
4383
+
4384
+ const wrapperPkg = tree . children . get ( 'wrapper-pkg' )
4385
+ const nestedDep = tree . children . get ( 'nested-dep' )
4386
+
4387
+ t . ok ( wrapperPkg , 'wrapper-pkg should be found' )
4388
+ t . ok ( wrapperPkg . isLink , 'wrapper-pkg should be a link (project-internal)' )
4389
+ t . ok ( nestedDep , 'nested-dep should be found' )
4390
+ t . ok ( nestedDep . isLink , 'nested-dep should be a link (project-internal)' )
4391
+ } )
4392
+ } )
0 commit comments