@@ -5,11 +5,14 @@ import {
55 mkdirSync ,
66 mkdtempSync ,
77 readFileSync ,
8+ readlinkSync ,
9+ realpathSync ,
810 rmSync ,
11+ symlinkSync ,
912 writeFileSync ,
1013} from 'node:fs' ;
1114import { tmpdir } from 'node:os' ;
12- import { join } from 'node:path' ;
15+ import { isAbsolute , join , relative } from 'node:path' ;
1316import { describe , expect , it } from 'vite-plus/test' ;
1417import {
1518 createIsolatedPlayground ,
@@ -100,3 +103,48 @@ it('clears the shutdown deadline after a real child exits', () => {
100103 expect ( result . status , result . stderr ) . toBe ( 0 ) ;
101104 expect ( result . stdout . trim ( ) ) . toBe ( '[]' ) ;
102105} , 20_000 ) ;
106+
107+ it ( 'resolves installed dependency links absolutely at the isolated fixture depth' , ( ) => {
108+ const workspace = mkdtempSync ( join ( tmpdir ( ) , 'void-fixture-dependencies-' ) ) ;
109+ const source = join ( workspace , 'playground' , 'app' ) ;
110+ const modules = join ( source , 'node_modules' ) ;
111+ mkdirSync ( join ( modules , '@fixture' ) , { recursive : true } ) ;
112+ writeFileSync ( join ( source , 'package.json' ) , JSON . stringify ( { name : 'dependency-app' } ) ) ;
113+ writeFileSync (
114+ join ( source , 'entry.mjs' ) ,
115+ 'import plain from "plain"; import scoped from "@fixture/scoped"; console.log(JSON.stringify([plain, scoped]));' ,
116+ ) ;
117+ for ( const name of [ 'plain' , '@fixture/scoped' ] ) {
118+ const installed = join ( workspace , 'packages' , name ) ;
119+ mkdirSync ( installed , { recursive : true } ) ;
120+ writeFileSync (
121+ join ( installed , 'package.json' ) ,
122+ JSON . stringify ( { name, type : 'module' , exports : './index.mjs' } ) ,
123+ ) ;
124+ writeFileSync ( join ( installed , 'index.mjs' ) , `export default ${ JSON . stringify ( name ) } ;` ) ;
125+ const link = join ( modules , name ) ;
126+ symlinkSync (
127+ relative ( join ( link , '..' ) , installed ) ,
128+ link ,
129+ process . platform === 'win32' ? 'junction' : 'dir' ,
130+ ) ;
131+ }
132+ const fixture = createIsolatedPlayground ( workspace , 'playground/app' ) ;
133+ try {
134+ for ( const name of [ 'plain' , '@fixture/scoped' ] ) {
135+ const link = join ( fixture . root , 'node_modules' , name ) ;
136+ expect ( isAbsolute ( readlinkSync ( link ) ) ) . toBe ( true ) ;
137+ expect ( realpathSync ( link ) ) . toBe ( realpathSync ( join ( workspace , 'packages' , name ) ) ) ;
138+ }
139+ const result = spawnSync ( process . execPath , [ 'entry.mjs' ] , {
140+ cwd : fixture . root ,
141+ encoding : 'utf8' ,
142+ timeout : 10_000 ,
143+ } ) ;
144+ expect ( result . status , result . stderr ) . toBe ( 0 ) ;
145+ expect ( JSON . parse ( result . stdout ) ) . toEqual ( [ 'plain' , '@fixture/scoped' ] ) ;
146+ } finally {
147+ fixture . cleanup ( ) ;
148+ rmSync ( workspace , { recursive : true , force : true } ) ;
149+ }
150+ } ) ;
0 commit comments