@@ -48,6 +48,14 @@ function writeDirsFile(options: unknown, bin: string): void {
4848 ) ;
4949}
5050
51+ function mockSuccessfulInstallOnce ( ) : void {
52+ vi . mocked ( exec ) . mockImplementationOnce ( async ( _command , _args , options ) => {
53+ const env = ( options as { env : Record < string , string > } ) . env ;
54+ if ( env . SETUP_VP_DIRS_FILE ) writeDirsFile ( options , "/test/data/bin" ) ;
55+ return 0 ;
56+ } ) ;
57+ }
58+
5159describe ( "installVitePlus" , ( ) => {
5260 // installVitePlus spreads process.env into the child env, so a VP_PR_VERSION
5361 // inherited from the runner (setup-vp's own CI sets it) would make these tests
@@ -82,7 +90,7 @@ describe("installVitePlus", () => {
8290 vi . stubEnv ( "PATH" , "/usr/bin" ) ;
8391 vi . stubEnv ( "VP_VPDIRS_AWARE" , "1" ) ;
8492 vi . stubEnv ( "SETUP_VP_DIRS_FILE" , "/tmp/stale-vp-dirs" ) ;
85- vi . mocked ( exec ) . mockResolvedValueOnce ( 0 ) ;
93+ mockSuccessfulInstallOnce ( ) ;
8694
8795 await installVitePlus ( { ...baseInputs , version : "0.2.9" } ) ;
8896
@@ -94,8 +102,30 @@ describe("installVitePlus", () => {
94102 expect ( ( options as { env : Record < string , string > } ) . env . SETUP_VP_DIRS_FILE ) . toBeUndefined ( ) ;
95103 } ) ;
96104
105+ it . each ( [
106+ { version : "0.3.0" , output : undefined } ,
107+ { version : `0.0.0-commit.${ commitSha } ` , output : "bin\t/test/data/bin\n" } ,
108+ { version : "latest" , output : "" } ,
109+ ] ) ( "should fail when $version does not report valid VpDirs" , async ( { version, output } ) => {
110+ vi . mocked ( exec ) . mockImplementationOnce ( async ( _command , _args , options ) => {
111+ if ( output !== undefined ) {
112+ const env = ( options as { env : Record < string , string > } ) . env ;
113+ writeFileSync ( env . SETUP_VP_DIRS_FILE , output ) ;
114+ }
115+ return 0 ;
116+ } ) ;
117+
118+ await expect ( installVitePlus ( { ...baseInputs , version } ) ) . rejects . toThrow (
119+ "Vite+ was installed successfully, but setup-vp could not resolve its VpDirs." ,
120+ ) ;
121+
122+ expect ( exec ) . toHaveBeenCalledTimes ( 1 ) ;
123+ expect ( addPath ) . not . toHaveBeenCalled ( ) ;
124+ } ) ;
125+
97126 it ( "should retry on transient failure and eventually succeed" , async ( ) => {
98- vi . mocked ( exec ) . mockResolvedValueOnce ( 6 ) . mockResolvedValueOnce ( 6 ) . mockResolvedValueOnce ( 0 ) ;
127+ vi . mocked ( exec ) . mockResolvedValueOnce ( 6 ) . mockResolvedValueOnce ( 6 ) ;
128+ mockSuccessfulInstallOnce ( ) ;
99129
100130 await installVitePlus ( baseInputs ) ;
101131
@@ -112,7 +142,8 @@ describe("installVitePlus", () => {
112142 } ) ;
113143
114144 it ( "should retry when exec itself throws (e.g. process spawn error)" , async ( ) => {
115- vi . mocked ( exec ) . mockRejectedValueOnce ( new Error ( "spawn bash ENOENT" ) ) . mockResolvedValueOnce ( 0 ) ;
145+ vi . mocked ( exec ) . mockRejectedValueOnce ( new Error ( "spawn bash ENOENT" ) ) ;
146+ mockSuccessfulInstallOnce ( ) ;
116147
117148 await installVitePlus ( baseInputs ) ;
118149
@@ -121,7 +152,8 @@ describe("installVitePlus", () => {
121152 } ) ;
122153
123154 it ( "should fall back to the GitHub install URL after a single primary failure" , async ( ) => {
124- vi . mocked ( exec ) . mockResolvedValueOnce ( 35 ) . mockResolvedValueOnce ( 0 ) ;
155+ vi . mocked ( exec ) . mockResolvedValueOnce ( 35 ) ;
156+ mockSuccessfulInstallOnce ( ) ;
125157
126158 await installVitePlus ( baseInputs ) ;
127159
@@ -157,7 +189,7 @@ describe("installVitePlus", () => {
157189 ] ) (
158190 "should install $desc with the install script from their git ref" ,
159191 async ( { version, ref } ) => {
160- vi . mocked ( exec ) . mockResolvedValueOnce ( 0 ) ;
192+ mockSuccessfulInstallOnce ( ) ;
161193
162194 await installVitePlus ( { ...baseInputs , version } ) ;
163195
@@ -169,7 +201,8 @@ describe("installVitePlus", () => {
169201 ) ;
170202
171203 it ( "should fall back to the jsDelivr mirror of the pinned script on failure" , async ( ) => {
172- vi . mocked ( exec ) . mockResolvedValueOnce ( 35 ) . mockResolvedValueOnce ( 0 ) ;
204+ vi . mocked ( exec ) . mockResolvedValueOnce ( 35 ) ;
205+ mockSuccessfulInstallOnce ( ) ;
173206
174207 await installVitePlus ( { ...baseInputs , version : "0.2.9" } ) ;
175208
@@ -188,8 +221,8 @@ describe("installVitePlus", () => {
188221 . mockResolvedValueOnce ( 22 )
189222 . mockResolvedValueOnce ( 22 )
190223 . mockResolvedValueOnce ( 22 )
191- . mockResolvedValueOnce ( 22 )
192- . mockResolvedValueOnce ( 0 ) ;
224+ . mockResolvedValueOnce ( 22 ) ;
225+ mockSuccessfulInstallOnce ( ) ;
193226
194227 await installVitePlus ( { ...baseInputs , version : "0.2.9" } ) ;
195228
@@ -215,7 +248,7 @@ describe("installVitePlus", () => {
215248 } ) ;
216249
217250 it ( "should source the downloaded bash installer and dump its resolved directories" , async ( ) => {
218- vi . mocked ( exec ) . mockResolvedValueOnce ( 0 ) ;
251+ mockSuccessfulInstallOnce ( ) ;
219252
220253 await installVitePlus ( baseInputs ) ;
221254
@@ -232,7 +265,7 @@ describe("installVitePlus", () => {
232265 } ) ;
233266
234267 it ( "should declare VpDirs support to the installer" , async ( ) => {
235- vi . mocked ( exec ) . mockResolvedValueOnce ( 0 ) ;
268+ mockSuccessfulInstallOnce ( ) ;
236269
237270 await installVitePlus ( baseInputs ) ;
238271
@@ -259,7 +292,7 @@ describe("installVitePlus", () => {
259292 expected : undefined ,
260293 } ,
261294 ] ) ( "$desc" , async ( { version, expected } ) => {
262- vi . mocked ( exec ) . mockResolvedValueOnce ( 0 ) ;
295+ mockSuccessfulInstallOnce ( ) ;
263296
264297 await installVitePlus ( { ...baseInputs , version } ) ;
265298
@@ -284,7 +317,7 @@ describe("installVitePlus", () => {
284317 expected : undefined ,
285318 } ,
286319 ] ) ( "$desc" , async ( { nodeManager, expected } ) => {
287- vi . mocked ( exec ) . mockResolvedValueOnce ( 0 ) ;
320+ mockSuccessfulInstallOnce ( ) ;
288321
289322 await installVitePlus ( { ...baseInputs , nodeManager } ) ;
290323
0 commit comments