@@ -37,10 +37,15 @@ vi.mock("proper-lockfile", () => ({
3737} ) )
3838
3939// Mock fs (createWriteStream and createReadStream for checksum verification)
40+ let closeHandler : ( ( ) => void ) | undefined
4041const mockWriteStream = {
4142 on : vi . fn ( ) ,
4243 close : vi . fn ( ) ,
4344}
45+ const onWriteStreamEvent = ( event : string , callback : ( ) => void ) => {
46+ if ( event === "finish" ) setImmediate ( callback )
47+ if ( event === "close" ) closeHandler = callback
48+ }
4449vi . mock ( "fs" , ( ) => ( {
4550 createWriteStream : vi . fn ( ( ) => mockWriteStream ) ,
4651 createReadStream : vi . fn ( ( ) => {
@@ -107,8 +112,9 @@ describe("SEMBLE_SHA256 checksum fixture", () => {
107112describe ( "semble-downloader" , ( ) => {
108113 beforeEach ( ( ) => {
109114 vi . clearAllMocks ( )
110- mockWriteStream . on = vi . fn ( )
111- mockWriteStream . close = vi . fn ( )
115+ closeHandler = undefined
116+ mockWriteStream . on = vi . fn ( onWriteStreamEvent )
117+ mockWriteStream . close = vi . fn ( ( ) => closeHandler ?.( ) )
112118
113119 // Restore the default https.get mock so tests that override it don't leak
114120 ; ( https . get as any ) . mockImplementation ( ( _url : string , callback : ( res : any ) => void ) => {
@@ -227,13 +233,6 @@ describe("semble-downloader", () => {
227233 // No version file exists
228234 ; ( fs . readFile as any ) . mockRejectedValue ( new Error ( "ENOENT" ) )
229235
230- // Simulate successful download: pipe is called, then "finish" fires
231- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
232- if ( event === "finish" ) {
233- setImmediate ( cb )
234- }
235- } )
236-
237236 try {
238237 const result = await downloadSemble ( "/storage" )
239238
@@ -382,12 +381,6 @@ describe("semble-downloader", () => {
382381 } )
383382
384383 // Simulate successful download on the second response
385- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
386- if ( event === "finish" ) {
387- setImmediate ( cb )
388- }
389- } )
390-
391384 try {
392385 const result = await downloadSemble ( "/storage" )
393386
@@ -550,12 +543,6 @@ describe("semble-downloader", () => {
550543 ; ( fs . readFile as any ) . mockRejectedValue ( new Error ( "ENOENT" ) )
551544
552545 // Simulate successful download
553- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
554- if ( event === "finish" ) {
555- setImmediate ( cb )
556- }
557- } )
558-
559546 try {
560547 const result = await downloadSemble ( "/storage" )
561548
@@ -590,12 +577,6 @@ describe("semble-downloader", () => {
590577 ; ( fs . readFile as any ) . mockRejectedValue ( new Error ( "ENOENT" ) )
591578
592579 // Simulate successful download
593- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
594- if ( event === "finish" ) {
595- setImmediate ( cb )
596- }
597- } )
598-
599580 // Archive cleanup fails but should not throw (only archive removal after extraction)
600581 ; ( fs . rm as any ) . mockRejectedValueOnce ( new Error ( "archive cleanup failed" ) )
601582
@@ -625,12 +606,6 @@ describe("semble-downloader", () => {
625606 ; ( fs . access as any ) . mockResolvedValue ( undefined )
626607
627608 // Simulate successful download
628- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
629- if ( event === "finish" ) {
630- setImmediate ( cb )
631- }
632- } )
633-
634609 try {
635610 const result = await downloadSemble ( "/storage" )
636611
@@ -681,12 +656,6 @@ describe("semble-downloader", () => {
681656 ; ( fs . access as any ) . mockResolvedValue ( undefined )
682657
683658 // Simulate successful download
684- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
685- if ( event === "finish" ) {
686- setImmediate ( cb )
687- }
688- } )
689-
690659 try {
691660 const result = await downloadSemble ( "/storage" )
692661
@@ -781,12 +750,6 @@ describe("semble-downloader", () => {
781750 } )
782751
783752 // Simulate successful download
784- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
785- if ( event === "finish" ) {
786- setImmediate ( cb )
787- }
788- } )
789-
790753 try {
791754 const result = await downloadSemble ( "/storage" )
792755
@@ -824,12 +787,6 @@ describe("semble-downloader", () => {
824787 ; ( fs . access as any ) . mockResolvedValue ( undefined )
825788
826789 // Simulate successful download
827- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
828- if ( event === "finish" ) {
829- setImmediate ( cb )
830- }
831- } )
832-
833790 try {
834791 const result = await downloadSemble ( "/storage" )
835792
@@ -868,12 +825,6 @@ describe("semble-downloader", () => {
868825 // readdir rejects — exercises the catch block in cleanupStaleArchives
869826 ; ( fs . readdir as any ) . mockRejectedValue ( new Error ( "EACCES" ) )
870827
871- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
872- if ( event === "finish" ) {
873- setImmediate ( cb )
874- }
875- } )
876-
877828 try {
878829 const result = await downloadSemble ( "/storage" )
879830
@@ -904,12 +855,6 @@ describe("semble-downloader", () => {
904855 "unrelated.txt" ,
905856 ] )
906857
907- mockWriteStream . on . mockImplementation ( ( event : string , cb : ( ) => void ) => {
908- if ( event === "finish" ) {
909- setImmediate ( cb )
910- }
911- } )
912-
913858 try {
914859 await downloadSemble ( "/storage" )
915860
0 commit comments