11import { promises as fs } from "fs" ;
22import { vi , describe , it , expect , beforeEach } from "vitest" ;
33import { getDirSize } from "../fileUtils" ;
4- import { FolderScanner , type IMessagePort , type WorkerResponse } from "../appDataScanWorker" ;
4+ import { FolderScanner , initializeWorker , type IMessagePort , type WorkerResponse } from "../appDataScanWorker" ;
5+ import path from "path" ;
56
67// Mock modules
78vi . mock ( "fs" , ( ) => ( {
@@ -32,6 +33,11 @@ describe("FolderScanner", () => {
3233 mockMessagePort = {
3334 postMessage : ( msg : WorkerResponse ) => {
3435 messages . push ( msg ) ;
36+ } ,
37+ on : ( event : "message" , listener : ( message : WorkerResponse ) => void ) => {
38+ if ( event === "message" ) {
39+ listener ( messages [ messages . length - 1 ] ) ;
40+ }
3541 }
3642 } ;
3743
@@ -58,19 +64,26 @@ describe("FolderScanner", () => {
5864 ] as any ) ;
5965
6066 const results = await scanner . scanPaths ( paths , 2 , keywords ) ;
67+ scanner . sendFolders ( true ) ; // Force send any remaining folders
6168
6269 expect ( results ) . toHaveLength ( 2 ) ;
6370 expect ( messages ) . toContainEqual ( { type : "current-path" , path : paths [ 0 ] } ) ;
6471 expect ( messages ) . toContainEqual ( { type : "current-path" , path : paths [ 1 ] } ) ;
65- expect ( messages ) . toContainEqual ( {
66- type : "folder-found" ,
67- folder : expect . objectContaining ( { name : "cache-dir" } )
68- } ) ;
69- expect ( messages ) . toContainEqual ( {
70- type : "folder-found" ,
71- folder : expect . objectContaining ( { name : "temp-dir" } )
72- } ) ;
73- expect ( messages ) . toContainEqual ( { type : "progress" , count : 1 } ) ;
72+
73+ // Find all folder-found messages
74+ const folderFoundMessages = messages . filter ( m => m . type === "folder-found" ) ;
75+ expect ( folderFoundMessages ) . toHaveLength ( 1 ) ; // We expect one final batched message
76+
77+ // Verify the folders in the message - order doesn't matter since they're batched
78+ const foundFolders = folderFoundMessages [ 0 ] . folders ;
79+ expect ( foundFolders ) . toHaveLength ( 2 ) ;
80+ expect ( foundFolders ) . toEqual (
81+ expect . arrayContaining ( [
82+ expect . objectContaining ( { name : "cache-dir" , size : 1234 } ) ,
83+ expect . objectContaining ( { name : "temp-dir" , size : 1234 } )
84+ ] )
85+ ) ;
86+
7487 expect ( messages ) . toContainEqual ( { type : "progress" , count : 2 } ) ;
7588 expect ( messages ) . toContainEqual ( { type : "done" , results } ) ;
7689 } ) ;
@@ -140,9 +153,89 @@ describe("FolderScanner", () => {
140153 ] as any ) ;
141154
142155 const results = await scanner . scanPaths ( [ "/test" ] , 1 , [ "cache" ] ) ;
156+ scanner . sendFolders ( true ) ; // Force send any remaining folders
143157
144158 expect ( results ) . toHaveLength ( 3 ) ;
145- expect ( messages . filter ( m => m . type === "folder-found" ) ) . toHaveLength ( 3 ) ;
159+ // Since folders are now batched, we expect one message with all 3 folders
160+ const folderFoundMessages = messages . filter ( m => m . type === "folder-found" ) ;
161+ expect ( folderFoundMessages ) . toHaveLength ( 1 ) ;
162+
163+ // Verify all folders are in the final batched message
164+ const foundFolders = folderFoundMessages [ 0 ] . folders ;
165+ expect ( foundFolders ) . toHaveLength ( 3 ) ;
166+ expect ( foundFolders ) . toEqual (
167+ expect . arrayContaining ( [
168+ expect . objectContaining ( { name : "CACHE" , size : 1234 } ) ,
169+ expect . objectContaining ( { name : "Cache" , size : 1234 } ) ,
170+ expect . objectContaining ( { name : "cache" , size : 1234 } )
171+ ] )
172+ ) ;
173+ } ) ;
174+
175+ it ( "should handle error when path normalization fails" , async ( ) => {
176+ // Mock path.normalize to throw
177+ const originalNormalize = path . normalize ;
178+ path . normalize = vi . fn ( ) . mockImplementation ( ( ) => {
179+ throw new Error ( "Invalid path" ) ;
180+ } ) ;
181+
182+ try {
183+ const results = await scanner . scanPaths ( [ "/test/path" ] , 1 , [ "cache" ] ) ;
184+
185+ expect ( messages ) . toEqual ( [
186+ {
187+ type : "error" ,
188+ error : "Invalid path"
189+ }
190+ ] ) ;
191+
192+ expect ( results ) . toEqual ( [ ] ) ;
193+ } finally {
194+ // Restore original normalize function
195+ path . normalize = originalNormalize ;
196+ }
197+ } ) ;
198+
199+ it ( "initialize worker without parentPort throws error" , ( ) => {
200+ expect ( ( ) => initializeWorker ( ) ) . toThrowError ( "Worker thread parent port not available" ) ;
201+ } ) ;
202+
203+ it ( "initialize worker with injected port" , ( ) => {
204+ let functions : any [ ] = [ ] ;
205+ const port = {
206+ postMessage : ( message : WorkerResponse ) => {
207+ messages . push ( message ) ;
208+ } ,
209+ on : ( event : string , listener : ( message : WorkerResponse ) => void ) => {
210+ functions . push ( listener ) ;
211+ }
212+ } as unknown as IMessagePort ;
213+ initializeWorker ( port ) ;
214+ expect ( functions ) . toHaveLength ( 1 ) ;
215+ expect ( functions [ 0 ] ) . toBeDefined ( ) ;
216+
217+ // call function message.paths, message.maxDepth, message.keywords
218+ functions [ 0 ] ( {
219+ type : "message" ,
220+ data : {
221+ paths : [ "/test" ] ,
222+ maxDepth : 1 ,
223+ keywords : [ "cache" ]
224+ }
225+ } ) ;
226+
227+ expect ( messages ) . toContainEqual ( {
228+ "error" : "paths is not iterable" ,
229+ "type" : "error"
230+ } ) ;
231+
232+ functions [ 0 ] ( {
233+ type : "stop" ,
234+ } ) ;
235+
236+ expect ( messages ) . toContainEqual ( {
237+ "type" : "stop"
238+ } ) ;
146239 } ) ;
147240 } ) ;
148241} ) ;
0 commit comments