1616import {
1717 defaultIgnore ,
1818 getGlobMatcher ,
19+ glob ,
1920 globStreamLicenses ,
21+ globSync ,
2022} from '@socketsecurity/lib/globs'
2123import { describe , expect , it } from 'vitest'
2224
@@ -174,6 +176,18 @@ describe('globs', () => {
174176 expect ( matcher ( 'src/app.js' ) ) . toBe ( true )
175177 expect ( matcher ( 'src/utils/helper.js' ) ) . toBe ( true )
176178 } )
179+
180+ it ( 'should handle only negative patterns' , ( ) => {
181+ const matcher = getGlobMatcher ( [ '!*.test.js' , '!*.spec.js' ] )
182+ expect ( typeof matcher ) . toBe ( 'function' )
183+ } )
184+
185+ it ( 'should map negative patterns correctly' , ( ) => {
186+ const matcher = getGlobMatcher ( [ '*.js' , '!test/*.js' , '!spec/*.js' ] )
187+ expect ( matcher ( 'app.js' ) ) . toBe ( true )
188+ expect ( matcher ( 'test/app.js' ) ) . toBe ( false )
189+ expect ( matcher ( 'spec/app.js' ) ) . toBe ( false )
190+ } )
177191 } )
178192
179193 describe ( 'globStreamLicenses' , ( ) => {
@@ -184,6 +198,19 @@ describe('globs', () => {
184198 expect ( typeof stream . pipe ) . toBe ( 'function' )
185199 } )
186200
201+ it ( 'should stream license files' , async ( ) => {
202+ const files : string [ ] = [ ]
203+ const stream = globStreamLicenses ( process . cwd ( ) , { recursive : false } )
204+
205+ await new Promise < void > ( ( resolve , reject ) => {
206+ stream . on ( 'data' , ( file : string ) => files . push ( file ) )
207+ stream . on ( 'end' , ( ) => resolve ( ) )
208+ stream . on ( 'error' , reject )
209+ } )
210+
211+ expect ( Array . isArray ( files ) ) . toBe ( true )
212+ } )
213+
187214 it ( 'should accept dirname parameter' , ( ) => {
188215 expect ( ( ) => globStreamLicenses ( '.' ) ) . not . toThrow ( )
189216 expect ( ( ) => globStreamLicenses ( './src' ) ) . not . toThrow ( )
@@ -194,19 +221,50 @@ describe('globs', () => {
194221 expect ( ( ) => globStreamLicenses ( '.' , { recursive : true } ) ) . not . toThrow ( )
195222 } )
196223
197- it ( 'should handle ignoreOriginals option' , ( ) => {
198- const stream = globStreamLicenses ( '.' , { ignoreOriginals : true } )
199- expect ( stream ) . toBeDefined ( )
224+ it ( 'should handle ignoreOriginals option' , async ( ) => {
225+ const files : string [ ] = [ ]
226+ const stream = globStreamLicenses ( process . cwd ( ) , {
227+ ignoreOriginals : true ,
228+ recursive : false ,
229+ } )
230+
231+ await new Promise < void > ( ( resolve , reject ) => {
232+ stream . on ( 'data' , ( file : string ) => files . push ( file ) )
233+ stream . on ( 'end' , ( ) => resolve ( ) )
234+ stream . on ( 'error' , reject )
235+ } )
236+
237+ // Should not include files matching *.original pattern
238+ expect ( files . every ( f => ! f . includes ( '.original' ) ) ) . toBe ( true )
200239 } )
201240
202- it ( 'should handle recursive option' , ( ) => {
203- const stream = globStreamLicenses ( '.' , { recursive : false } )
204- expect ( stream ) . toBeDefined ( )
241+ it ( 'should handle recursive option' , async ( ) => {
242+ const files : string [ ] = [ ]
243+ const stream = globStreamLicenses ( process . cwd ( ) , { recursive : true } )
244+
245+ await new Promise < void > ( ( resolve , reject ) => {
246+ stream . on ( 'data' , ( file : string ) => files . push ( file ) )
247+ stream . on ( 'end' , ( ) => resolve ( ) )
248+ stream . on ( 'error' , reject )
249+ } )
250+
251+ expect ( Array . isArray ( files ) ) . toBe ( true )
205252 } )
206253
207- it ( 'should handle custom ignore patterns' , ( ) => {
208- const stream = globStreamLicenses ( '.' , { ignore : [ '**/node_modules/**' ] } )
209- expect ( stream ) . toBeDefined ( )
254+ it ( 'should handle custom ignore patterns as array' , async ( ) => {
255+ const files : string [ ] = [ ]
256+ const stream = globStreamLicenses ( process . cwd ( ) , {
257+ ignore : [ '**/test/**' , '**/node_modules/**' ] ,
258+ recursive : false ,
259+ } )
260+
261+ await new Promise < void > ( ( resolve , reject ) => {
262+ stream . on ( 'data' , ( file : string ) => files . push ( file ) )
263+ stream . on ( 'end' , ( ) => resolve ( ) )
264+ stream . on ( 'error' , reject )
265+ } )
266+
267+ expect ( Array . isArray ( files ) ) . toBe ( true )
210268 } )
211269
212270 it ( 'should handle absolute option' , ( ) => {
@@ -229,14 +287,22 @@ describe('globs', () => {
229287 expect ( stream ) . toBeDefined ( )
230288 } )
231289
232- it ( 'should handle multiple options together' , ( ) => {
233- const stream = globStreamLicenses ( '.' , {
290+ it ( 'should handle multiple options together' , async ( ) => {
291+ const files : string [ ] = [ ]
292+ const stream = globStreamLicenses ( process . cwd ( ) , {
234293 recursive : true ,
235294 ignoreOriginals : true ,
236295 dot : true ,
237296 absolute : true ,
238297 } )
239- expect ( stream ) . toBeDefined ( )
298+
299+ await new Promise < void > ( ( resolve , reject ) => {
300+ stream . on ( 'data' , ( file : string ) => files . push ( file ) )
301+ stream . on ( 'end' , ( ) => resolve ( ) )
302+ stream . on ( 'error' , reject )
303+ } )
304+
305+ expect ( Array . isArray ( files ) ) . toBe ( true )
240306 } )
241307
242308 it ( 'should be a function' , ( ) => {
@@ -250,6 +316,178 @@ describe('globs', () => {
250316 } )
251317 } )
252318
319+ describe ( 'glob' , ( ) => {
320+ it ( 'should be a function' , ( ) => {
321+ expect ( typeof glob ) . toBe ( 'function' )
322+ } )
323+
324+ it ( 'should return a promise' , ( ) => {
325+ const result = glob ( '*.js' )
326+ expect ( result ) . toBeInstanceOf ( Promise )
327+ } )
328+
329+ it ( 'should find files matching pattern' , async ( ) => {
330+ const files = await glob ( '*.json' , { cwd : process . cwd ( ) } )
331+ expect ( Array . isArray ( files ) ) . toBe ( true )
332+ expect ( files . length ) . toBeGreaterThan ( 0 )
333+ expect ( files . some ( f => f . includes ( 'package.json' ) ) ) . toBe ( true )
334+ } )
335+
336+ it ( 'should accept array of patterns' , async ( ) => {
337+ const files = await glob ( [ '*.json' , '*.md' ] , { cwd : process . cwd ( ) } )
338+ expect ( Array . isArray ( files ) ) . toBe ( true )
339+ } )
340+
341+ it ( 'should respect cwd option' , async ( ) => {
342+ const files = await glob ( '*.ts' , { cwd : 'src' } )
343+ expect ( Array . isArray ( files ) ) . toBe ( true )
344+ } )
345+
346+ it ( 'should handle ignore patterns' , async ( ) => {
347+ const files = await glob ( '**/*.ts' , {
348+ cwd : 'src' ,
349+ ignore : [ '**/paths/**' ] ,
350+ } )
351+ expect ( Array . isArray ( files ) ) . toBe ( true )
352+ expect ( files . every ( f => ! f . includes ( 'paths/' ) ) ) . toBe ( true )
353+ } )
354+
355+ it ( 'should handle absolute option' , async ( ) => {
356+ const files = await glob ( '*.json' , {
357+ cwd : process . cwd ( ) ,
358+ absolute : true ,
359+ } )
360+ expect ( Array . isArray ( files ) ) . toBe ( true )
361+ if ( files . length > 0 ) {
362+ expect ( files [ 0 ] . startsWith ( '/' ) ) . toBe ( true )
363+ }
364+ } )
365+
366+ it ( 'should handle onlyFiles option' , async ( ) => {
367+ const files = await glob ( '*' , { cwd : process . cwd ( ) , onlyFiles : true } )
368+ expect ( Array . isArray ( files ) ) . toBe ( true )
369+ } )
370+
371+ it ( 'should handle dot option' , async ( ) => {
372+ const files = await glob ( '.*' , { cwd : process . cwd ( ) , dot : true } )
373+ expect ( Array . isArray ( files ) ) . toBe ( true )
374+ } )
375+
376+ it ( 'should handle empty pattern array' , async ( ) => {
377+ const files = await glob ( [ ] , { cwd : process . cwd ( ) } )
378+ expect ( Array . isArray ( files ) ) . toBe ( true )
379+ expect ( files . length ) . toBe ( 0 )
380+ } )
381+
382+ it ( 'should handle single pattern string' , async ( ) => {
383+ const files = await glob ( 'package.json' , { cwd : process . cwd ( ) } )
384+ expect ( Array . isArray ( files ) ) . toBe ( true )
385+ expect ( files . some ( f => f . includes ( 'package.json' ) ) ) . toBe ( true )
386+ } )
387+
388+ it ( 'should handle negation patterns' , async ( ) => {
389+ const files = await glob ( [ '*.json' , '!package-lock.json' ] , {
390+ cwd : process . cwd ( ) ,
391+ } )
392+ expect ( Array . isArray ( files ) ) . toBe ( true )
393+ expect ( files . every ( f => ! f . includes ( 'package-lock.json' ) ) ) . toBe ( true )
394+ } )
395+
396+ it ( 'should work without options parameter' , async ( ) => {
397+ const files = await glob ( '*.json' )
398+ expect ( Array . isArray ( files ) ) . toBe ( true )
399+ } )
400+ } )
401+
402+ describe ( 'globSync' , ( ) => {
403+ it ( 'should be a function' , ( ) => {
404+ expect ( typeof globSync ) . toBe ( 'function' )
405+ } )
406+
407+ it ( 'should return an array' , ( ) => {
408+ const result = globSync ( '*.json' , { cwd : process . cwd ( ) } )
409+ expect ( Array . isArray ( result ) ) . toBe ( true )
410+ } )
411+
412+ it ( 'should find files matching pattern' , ( ) => {
413+ const files = globSync ( '*.json' , { cwd : process . cwd ( ) } )
414+ expect ( Array . isArray ( files ) ) . toBe ( true )
415+ expect ( files . length ) . toBeGreaterThan ( 0 )
416+ expect ( files . some ( f => f . includes ( 'package.json' ) ) ) . toBe ( true )
417+ } )
418+
419+ it ( 'should accept array of patterns' , ( ) => {
420+ const files = globSync ( [ '*.json' , '*.md' ] , { cwd : process . cwd ( ) } )
421+ expect ( Array . isArray ( files ) ) . toBe ( true )
422+ } )
423+
424+ it ( 'should respect cwd option' , ( ) => {
425+ const files = globSync ( '*.ts' , { cwd : 'src' } )
426+ expect ( Array . isArray ( files ) ) . toBe ( true )
427+ } )
428+
429+ it ( 'should handle ignore patterns' , ( ) => {
430+ const files = globSync ( '**/*.ts' , {
431+ cwd : 'src' ,
432+ ignore : [ '**/paths/**' ] ,
433+ } )
434+ expect ( Array . isArray ( files ) ) . toBe ( true )
435+ expect ( files . every ( f => ! f . includes ( 'paths/' ) ) ) . toBe ( true )
436+ } )
437+
438+ it ( 'should handle absolute option' , ( ) => {
439+ const files = globSync ( '*.json' , {
440+ cwd : process . cwd ( ) ,
441+ absolute : true ,
442+ } )
443+ expect ( Array . isArray ( files ) ) . toBe ( true )
444+ if ( files . length > 0 ) {
445+ expect ( files [ 0 ] . startsWith ( '/' ) ) . toBe ( true )
446+ }
447+ } )
448+
449+ it ( 'should handle onlyFiles option' , ( ) => {
450+ const files = globSync ( '*' , { cwd : process . cwd ( ) , onlyFiles : true } )
451+ expect ( Array . isArray ( files ) ) . toBe ( true )
452+ } )
453+
454+ it ( 'should handle dot option' , ( ) => {
455+ const files = globSync ( '.*' , { cwd : process . cwd ( ) , dot : true } )
456+ expect ( Array . isArray ( files ) ) . toBe ( true )
457+ } )
458+
459+ it ( 'should return same results as async glob' , async ( ) => {
460+ const syncFiles = globSync ( '*.json' , { cwd : process . cwd ( ) } )
461+ const asyncFiles = await glob ( '*.json' , { cwd : process . cwd ( ) } )
462+ expect ( syncFiles . sort ( ) ) . toEqual ( asyncFiles . sort ( ) )
463+ } )
464+
465+ it ( 'should handle empty pattern array' , ( ) => {
466+ const files = globSync ( [ ] , { cwd : process . cwd ( ) } )
467+ expect ( Array . isArray ( files ) ) . toBe ( true )
468+ expect ( files . length ) . toBe ( 0 )
469+ } )
470+
471+ it ( 'should handle single pattern string' , ( ) => {
472+ const files = globSync ( 'package.json' , { cwd : process . cwd ( ) } )
473+ expect ( Array . isArray ( files ) ) . toBe ( true )
474+ expect ( files . some ( f => f . includes ( 'package.json' ) ) ) . toBe ( true )
475+ } )
476+
477+ it ( 'should handle negation patterns' , ( ) => {
478+ const files = globSync ( [ '*.json' , '!package-lock.json' ] , {
479+ cwd : process . cwd ( ) ,
480+ } )
481+ expect ( Array . isArray ( files ) ) . toBe ( true )
482+ expect ( files . every ( f => ! f . includes ( 'package-lock.json' ) ) ) . toBe ( true )
483+ } )
484+
485+ it ( 'should work without options parameter' , ( ) => {
486+ const files = globSync ( '*.json' )
487+ expect ( Array . isArray ( files ) ) . toBe ( true )
488+ } )
489+ } )
490+
253491 describe ( 'integration' , ( ) => {
254492 it ( 'should have consistent behavior across calls' , ( ) => {
255493 const matcher1 = getGlobMatcher ( '*.js' )
0 commit comments