@@ -43,6 +43,37 @@ class EdgeCaseStorage
4343 bake_folder " ./storage_edge_cases"
4444end
4545
46+ # Test storage with include patterns - only .cr files
47+ class FilteredStorageInclude
48+ extend BakedFileSystem
49+ bake_folder " ./storage/filters" , include_patterns: [" **/*.cr" ]
50+ end
51+
52+ # Test storage with exclude patterns - exclude test directory
53+ class FilteredStorageExclude
54+ extend BakedFileSystem
55+ bake_folder " ./storage/filters" , exclude_patterns: [" **/test/*" ]
56+ end
57+
58+ # Test storage with both include and exclude patterns
59+ class FilteredStorageCombined
60+ extend BakedFileSystem
61+ bake_folder " ./storage/filters" , include_patterns: [" **/*.cr" , " **/*.md" ], exclude_patterns: [" **/test/*" ]
62+ end
63+
64+ # Test storage with patterns that result in empty set (unless allow_empty)
65+ class FilteredStorageEmpty
66+ extend BakedFileSystem
67+ bake_folder " ./storage/filters" , include_patterns: [" **/*.txt" ], allow_empty: true
68+ end
69+
70+ # This should raise an error at compile time - patterns match nothing and allow_empty is false
71+ # Commented out because it would prevent compilation
72+ # class FilteredStorageEmptyError
73+ # extend BakedFileSystem
74+ # bake_folder "./storage/filters", include_patterns: ["**/*.txt"]
75+ # end
76+
4677def read_slice (path )
4778 File .open(path, " rb" ) do |io |
4879 Slice (UInt8 ).new(io.size).tap do |buf |
5384
5485describe BakedFileSystem do
5586 it " load only files without hidden one" do
56- Storage .files.size.should eq(4 )
87+ Storage .files.size.should eq(10 ) # lorem.txt, images/sidekiq.png, string_encoding/*, filters/*
5788 Storage .get?(" .hidden/hidden_file.txt" ).should be_nil
5889 end
5990
@@ -115,7 +146,7 @@ describe BakedFileSystem do
115146 end
116147
117148 it " handles interpolation in content" do
118- String .new(Storage .get(" string_encoding/interpolation.gz" ).to_slice).should eq " \# {foo} \ { % macro %}\n "
149+ String .new(Storage .get(" string_encoding/interpolation.gz" ).to_slice).should eq " \# {foo} {% macro %}\n "
119150 end
120151
121152 describe " rewind functionality" do
@@ -580,4 +611,63 @@ describe BakedFileSystem do
580611 file.not_nil!.closed?.should be_true
581612 end
582613 end
614+
615+ describe " file filtering" do
616+ it " includes only files matching include patterns" do
617+ # Should only have .cr files
618+ FilteredStorageInclude .files.size.should eq(4 ) # src/main.cr, src/lib.cr, test/spec.cr, test/helper.cr
619+ FilteredStorageInclude .get?(" src/main.cr" ).should_not be_nil
620+ FilteredStorageInclude .get?(" src/lib.cr" ).should_not be_nil
621+ FilteredStorageInclude .get?(" test/spec.cr" ).should_not be_nil
622+ FilteredStorageInclude .get?(" test/helper.cr" ).should_not be_nil
623+ FilteredStorageInclude .get?(" docs/README.md" ).should be_nil
624+ FilteredStorageInclude .get?(" config.yml" ).should be_nil
625+ end
626+
627+ it " excludes files matching exclude patterns" do
628+ # Should have everything except test/* files
629+ FilteredStorageExclude .files.size.should eq(4 ) # src/*, docs/*, config.yml
630+ FilteredStorageExclude .get?(" src/main.cr" ).should_not be_nil
631+ FilteredStorageExclude .get?(" src/lib.cr" ).should_not be_nil
632+ FilteredStorageExclude .get?(" docs/README.md" ).should_not be_nil
633+ FilteredStorageExclude .get?(" config.yml" ).should_not be_nil
634+ FilteredStorageExclude .get?(" test/spec.cr" ).should be_nil
635+ FilteredStorageExclude .get?(" test/helper.cr" ).should be_nil
636+ end
637+
638+ it " applies both include and exclude patterns" do
639+ # Include *.cr and *.md, exclude test/*
640+ # Should have: src/*.cr and docs/*.md (not test/*.cr)
641+ FilteredStorageCombined .files.size.should eq(3 ) # src/main.cr, src/lib.cr, docs/README.md
642+ FilteredStorageCombined .get?(" src/main.cr" ).should_not be_nil
643+ FilteredStorageCombined .get?(" src/lib.cr" ).should_not be_nil
644+ FilteredStorageCombined .get?(" docs/README.md" ).should_not be_nil
645+ FilteredStorageCombined .get?(" test/spec.cr" ).should be_nil
646+ FilteredStorageCombined .get?(" test/helper.cr" ).should be_nil
647+ FilteredStorageCombined .get?(" config.yml" ).should be_nil
648+ end
649+
650+ it " handles empty result with allow_empty" do
651+ # No .txt files in filters directory, but allow_empty is true
652+ FilteredStorageEmpty .files.size.should eq(0 )
653+ end
654+
655+ it " filters are relative to baked directory" do
656+ # Patterns should match from the baked folder root, not absolute paths
657+ FilteredStorageInclude .get?(" src/main.cr" ).should_not be_nil
658+ # Not "/storage/filters/src/main.cr"
659+ end
660+
661+ it " can read content from filtered files" do
662+ file = FilteredStorageInclude .get(" src/main.cr" )
663+ content = file.gets_to_end
664+ content.should contain(" Main file" )
665+ end
666+
667+ it " empty result behavior respects allow_empty flag" do
668+ # FilteredStorageEmpty has allow_empty: true, so it should work with 0 files
669+ FilteredStorageEmpty .files.size.should eq(0 )
670+ # Without allow_empty: true, it would raise at compile time (tested manually)
671+ end
672+ end
583673end
0 commit comments