@@ -376,3 +376,162 @@ func createFileInPath(tb testing.TB, filePath string, content []byte) {
376
376
err = os .WriteFile (filePath , content , 0777 )
377
377
assert .NoError (tb , err )
378
378
}
379
+
380
+ func TestParseIgnoreRuleToGlobs (t * testing.T ) {
381
+ testCases := []struct {
382
+ name string
383
+ rule string
384
+ baseDir string
385
+ expectedGlobs []string
386
+ }{
387
+ {
388
+ name : "single slash has no effect" ,
389
+ rule : "/" ,
390
+ baseDir : "/tmp/test" ,
391
+ expectedGlobs : []string {},
392
+ },
393
+ {
394
+ name : "negated single slash has no effect" ,
395
+ rule : "!/" ,
396
+ baseDir : "/tmp/test" ,
397
+ expectedGlobs : []string {},
398
+ },
399
+ {
400
+ name : "slash with star ignores everything" ,
401
+ rule : "/*" ,
402
+ baseDir : "/tmp/test" ,
403
+ expectedGlobs : []string {
404
+ "/tmp/test/*/**" ,
405
+ "/tmp/test/*" ,
406
+ },
407
+ },
408
+ {
409
+ name : "root directory pattern" ,
410
+ rule : "/foo" ,
411
+ baseDir : "/tmp/test" ,
412
+ expectedGlobs : []string {
413
+ "/tmp/test/foo/**" ,
414
+ "/tmp/test/foo" ,
415
+ },
416
+ },
417
+ {
418
+ name : "root directory with trailing slash" ,
419
+ rule : "/foo/" ,
420
+ baseDir : "/tmp/test" ,
421
+ expectedGlobs : []string {
422
+ "/tmp/test/foo/**" ,
423
+ },
424
+ },
425
+ {
426
+ name : "non-root directory pattern" ,
427
+ rule : "foo" ,
428
+ baseDir : "/tmp/test" ,
429
+ expectedGlobs : []string {
430
+ "/tmp/test/**/foo/**" ,
431
+ "/tmp/test/**/foo" ,
432
+ },
433
+ },
434
+ {
435
+ name : "non-root directory with trailing slash" ,
436
+ rule : "foo/" ,
437
+ baseDir : "/tmp/test" ,
438
+ expectedGlobs : []string {
439
+ "/tmp/test/**/foo/**" ,
440
+ },
441
+ },
442
+ }
443
+
444
+ for _ , tc := range testCases {
445
+ t .Run (tc .name , func (t * testing.T ) {
446
+ globs := parseIgnoreRuleToGlobs (tc .rule , tc .baseDir )
447
+ assert .ElementsMatch (t , tc .expectedGlobs , globs ,
448
+ "Rule: %q, Expected: %v, Got: %v" , tc .rule , tc .expectedGlobs , globs )
449
+ })
450
+ }
451
+ }
452
+
453
+ func TestFileFilter_SlashPatternInGitIgnore (t * testing.T ) {
454
+ t .Run ("gitignore with single slash has no effect" , func (t * testing.T ) {
455
+ tempDir := t .TempDir ()
456
+
457
+ // Create test files
458
+ files := []string {
459
+ "file1.txt" ,
460
+ "file2.txt" ,
461
+ "subdir/file3.txt" ,
462
+ "subdir/nested/file4.txt" ,
463
+ }
464
+
465
+ for _ , file := range files {
466
+ filePath := filepath .Join (tempDir , file )
467
+ createFileInPath (t , filePath , []byte ("test content" ))
468
+ }
469
+
470
+ // Create .gitignore with "/"
471
+ gitignorePath := filepath .Join (tempDir , ".gitignore" )
472
+ createFileInPath (t , gitignorePath , []byte ("/" ))
473
+
474
+ // Test file filtering
475
+ fileFilter := NewFileFilter (tempDir , & log .Logger )
476
+ rules , err := fileFilter .GetRules ([]string {".gitignore" })
477
+ assert .NoError (t , err )
478
+
479
+ // Should only have default rules since "/" has no effect
480
+ assert .Equal (t , fileFilter .defaultRules , rules , "Rules should only contain default rules" )
481
+
482
+ // Get all files and filter them
483
+ allFiles := fileFilter .GetAllFiles ()
484
+ filteredFiles := fileFilter .GetFilteredFiles (allFiles , rules )
485
+
486
+ // Collect filtered files
487
+ var filteredFilesList []string
488
+ for file := range filteredFiles {
489
+ relPath , err := filepath .Rel (tempDir , file )
490
+ assert .NoError (t , err )
491
+ // Normalize path separators for cross-platform compatibility
492
+ filteredFilesList = append (filteredFilesList , filepath .ToSlash (relPath ))
493
+ }
494
+
495
+ // With "/" pattern, no files should be ignored (all files pass through)
496
+ expectedFiles := []string {".gitignore" , "file1.txt" , "file2.txt" , "subdir/file3.txt" , "subdir/nested/file4.txt" }
497
+ assert .ElementsMatch (t , expectedFiles , filteredFilesList , "All files should pass through filter" )
498
+ })
499
+
500
+ t .Run ("gitignore with /* ignores all files" , func (t * testing.T ) {
501
+ tempDir := t .TempDir ()
502
+
503
+ // Create test files
504
+ files := []string {
505
+ "file1.txt" ,
506
+ "file2.txt" ,
507
+ "subdir/file3.txt" ,
508
+ }
509
+
510
+ for _ , file := range files {
511
+ filePath := filepath .Join (tempDir , file )
512
+ createFileInPath (t , filePath , []byte ("test content" ))
513
+ }
514
+
515
+ // Create .gitignore with "/*"
516
+ gitignorePath := filepath .Join (tempDir , ".gitignore" )
517
+ createFileInPath (t , gitignorePath , []byte ("/*" ))
518
+
519
+ // Test file filtering
520
+ fileFilter := NewFileFilter (tempDir , & log .Logger )
521
+ rules , err := fileFilter .GetRules ([]string {".gitignore" })
522
+ assert .NoError (t , err )
523
+
524
+ // Get all files and filter them
525
+ allFiles := fileFilter .GetAllFiles ()
526
+ filteredFiles := fileFilter .GetFilteredFiles (allFiles , rules )
527
+
528
+ // Collect filtered files
529
+ var filteredFilesList []string
530
+ for file := range filteredFiles {
531
+ filteredFilesList = append (filteredFilesList , file )
532
+ }
533
+
534
+ // With "/*" pattern, all files should be ignored
535
+ assert .Empty (t , filteredFilesList , "All files should be filtered out with /* pattern" )
536
+ })
537
+ }
0 commit comments