1- import { chmodSync , mkdirSync , mkdtempSync , readFileSync , rmSync , writeFileSync } from "node:fs" ;
1+ import { mkdtempSync , rmSync } from "node:fs" ;
2+ import { spawnSync } from "node:child_process" ;
23import { EventEmitter } from "node:events" ;
34import type { IncomingMessage } from "node:http" ;
45import { tmpdir } from "node:os" ;
56import path from "node:path" ;
6- import { afterEach , describe , expect , it } from "vite-plus/test" ;
7+ import { afterEach , describe , expect , it , vi } from "vite-plus/test" ;
78import { downloadFile , getSfwAssetName , setupSfw } from "./install-sfw.js" ;
9+ import { commandPath } from "../ci/process.js" ;
10+
11+ vi . mock ( "node:child_process" , ( ) => ( { spawnSync : vi . fn ( ) } ) ) ;
12+ vi . mock ( "../ci/process.js" , ( ) => ( { commandPath : vi . fn ( ) } ) ) ;
813
914const tempDirs : string [ ] = [ ] ;
1015
@@ -14,11 +19,8 @@ function tempDir(): string {
1419 return dir ;
1520}
1621
17- function shellQuote ( value : string ) : string {
18- return `'${ value . replaceAll ( "'" , "'\\''" ) } '` ;
19- }
20-
2122afterEach ( ( ) => {
23+ vi . resetAllMocks ( ) ;
2224 for ( const dir of tempDirs . splice ( 0 ) ) {
2325 rmSync ( dir , { recursive : true , force : true } ) ;
2426 }
@@ -40,61 +42,44 @@ describe("GitLab sfw setup", () => {
4042 } ) ;
4143
4244 it ( "uses an existing sfw command from PATH" , async ( ) => {
43- const dir = tempDir ( ) ;
44- const binDir = path . join ( dir , "bin" ) ;
45- mkdirSync ( binDir ) ;
46- const sfwBin = path . join ( binDir , "sfw" ) ;
47- writeFileSync ( sfwBin , "#!/usr/bin/env sh\nexit 0\n" , "utf8" ) ;
48- chmodSync ( sfwBin , 0o755 ) ;
49-
50- const previousPath = process . env . PATH ;
51- try {
52- process . env . PATH = `${ binDir } :${ previousPath || "" } ` ;
53- expect ( await setupSfw ( [ { } ] , { SETUP_VP_SFW : "true" , PATH : process . env . PATH } ) ) . toBe ( "sfw" ) ;
54- } finally {
55- process . env . PATH = previousPath ;
56- }
45+ vi . mocked ( commandPath ) . mockReturnValue ( path . join ( tempDir ( ) , "sfw" ) ) ;
46+
47+ expect ( await setupSfw ( [ { } ] , { SETUP_VP_SFW : "true" } ) ) . toBe ( "sfw" ) ;
48+ expect ( commandPath ) . toHaveBeenCalledWith ( "sfw" ) ;
49+ expect ( spawnSync ) . not . toHaveBeenCalled ( ) ;
5750 } ) ;
5851
5952 it ( "uses curl for default downloads" , async ( ) => {
6053 const dir = tempDir ( ) ;
61- const binDir = path . join ( dir , "bin" ) ;
6254 const outputPath = path . join ( dir , "sfw" ) ;
63- const logFile = path . join ( dir , "curl.log" ) ;
64- mkdirSync ( binDir ) ;
65-
66- const curlBin = path . join ( binDir , "curl" ) ;
67- writeFileSync (
68- curlBin ,
55+ const curl = path . join ( dir , "bin with spaces" , "curl" ) ;
56+ vi . mocked ( commandPath ) . mockReturnValue ( curl ) ;
57+ vi . mocked ( spawnSync ) . mockReturnValue ( {
58+ pid : 1 ,
59+ output : [ ] ,
60+ stdout : Buffer . alloc ( 0 ) ,
61+ stderr : Buffer . alloc ( 0 ) ,
62+ status : 0 ,
63+ signal : null ,
64+ } ) ;
65+
66+ await downloadFile ( "https://example.test/sfw" , outputPath ) ;
67+
68+ expect ( commandPath ) . toHaveBeenCalledWith ( "curl" ) ;
69+ expect ( spawnSync ) . toHaveBeenCalledExactlyOnceWith (
70+ curl ,
6971 [
70- "#!/usr/bin/env sh" ,
71- `printf '%s\\n' "$*" > ${ shellQuote ( logFile ) } ` ,
72- 'out=""' ,
73- 'while [ "$#" -gt 0 ]; do' ,
74- ' if [ "$1" = "-o" ]; then' ,
75- " shift" ,
76- ' out="$1"' ,
77- " break" ,
78- " fi" ,
79- " shift" ,
80- "done" ,
81- 'printf "sfw" > "$out"' ,
82- ] . join ( "\n" ) ,
83- "utf8" ,
72+ "-fsSL" ,
73+ "--connect-timeout" ,
74+ "5" ,
75+ "--max-time" ,
76+ "60" ,
77+ "https://example.test/sfw" ,
78+ "-o" ,
79+ outputPath ,
80+ ] ,
81+ { stdio : "ignore" } ,
8482 ) ;
85- chmodSync ( curlBin , 0o755 ) ;
86-
87- const previousPath = process . env . PATH ;
88- try {
89- process . env . PATH = `${ binDir } :${ previousPath || "" } ` ;
90- await downloadFile ( "https://example.test/sfw" , outputPath ) ;
91- } finally {
92- process . env . PATH = previousPath ;
93- }
94-
95- expect ( readFileSync ( outputPath , "utf8" ) ) . toBe ( "sfw" ) ;
96- expect ( readFileSync ( logFile , "utf8" ) ) . toContain ( "https://example.test/sfw" ) ;
97- expect ( readFileSync ( logFile , "utf8" ) ) . toContain ( "--max-time 60" ) ;
9883 } ) ;
9984
10085 it ( "times out stalled downloads" , async ( ) => {
0 commit comments