@@ -23,6 +23,7 @@ use tree_sitter_graph::Variables;
2323
2424use crate :: cli:: util:: ExistingPathBufValueParser ;
2525use crate :: cli:: util:: PathSpec ;
26+ use crate :: loader:: ContentProvider ;
2627use crate :: loader:: FileReader ;
2728use crate :: loader:: LanguageConfiguration ;
2829use crate :: loader:: Loader ;
@@ -55,7 +56,7 @@ use super::util::FileLogger;
5556 placeholders are correctly subtituted for all paths.
5657"# ) ]
5758pub struct TestArgs {
58- /// Test file or directory paths.
59+ /// Test file or directory paths. Files or files inside directories ending in .skip are excluded.
5960 #[ clap(
6061 value_name = "TEST_PATH" ,
6162 required = true ,
@@ -196,24 +197,37 @@ impl TestArgs {
196197 loader : & mut Loader ,
197198 file_status : & mut ConsoleFileLogger ,
198199 ) -> anyhow:: Result < TestResult > {
199- if self . show_skipped && test_path. extension ( ) . map_or ( false , |e| e == "skip" ) {
200- file_status. warning ( "skipped" , None ) ;
201- return Ok ( TestResult :: new ( ) ) ;
202- }
203-
204200 let cancellation_flag = & NoCancellation ;
205201
206- let mut file_reader = FileReader :: new ( ) ;
207- let lc = match loader. load_for_file ( test_path, & mut file_reader, cancellation_flag) ? {
202+ // If the file is skipped (ending in .skip) we construct the non-skipped path to see if we would support it.
203+ let load_path = if test_path. extension ( ) . map_or ( false , |e| e == "skip" ) {
204+ test_path. with_extension ( "" )
205+ } else {
206+ test_path. to_path_buf ( )
207+ } ;
208+ let mut file_reader = MappingFileReader :: new ( & load_path, test_path) ;
209+ let lc = match loader. load_for_file ( & load_path, & mut file_reader, cancellation_flag) ? {
208210 Some ( sgl) => sgl,
209211 None => return Ok ( TestResult :: new ( ) ) ,
210212 } ;
211- let source = file_reader. get ( test_path) ?;
213+
214+ if test_path. components ( ) . any ( |c| match c {
215+ std:: path:: Component :: Normal ( name) => ( name. as_ref ( ) as & Path )
216+ . extension ( )
217+ . map_or ( false , |e| e == "skip" ) ,
218+ _ => false ,
219+ } ) {
220+ if self . show_skipped {
221+ file_status. warning ( "skipped" , None ) ;
222+ }
223+ return Ok ( TestResult :: new ( ) ) ;
224+ }
212225
213226 file_status. processing ( ) ;
214227
228+ let source = file_reader. get ( test_path) ?;
215229 let default_fragment_path = test_path. strip_prefix ( test_root) . unwrap ( ) ;
216- let mut test = Test :: from_source ( & test_path, & source, default_fragment_path) ?;
230+ let mut test = Test :: from_source ( test_path, source, default_fragment_path) ?;
217231 if !self . no_builtins {
218232 self . load_builtins_into ( & lc, & mut test. graph ) ?;
219233 }
@@ -467,3 +481,34 @@ impl TestArgs {
467481 Ok ( ( ) )
468482 }
469483}
484+
485+ struct MappingFileReader < ' a > {
486+ inner : FileReader ,
487+ instead_of : & ' a Path ,
488+ load : & ' a Path ,
489+ }
490+
491+ impl < ' a > MappingFileReader < ' a > {
492+ fn new ( instead_of : & ' a Path , load : & ' a Path ) -> Self {
493+ Self {
494+ inner : FileReader :: new ( ) ,
495+ instead_of,
496+ load,
497+ }
498+ }
499+
500+ fn get ( & mut self , path : & Path ) -> std:: io:: Result < & str > {
501+ let path = if path == self . instead_of {
502+ self . load
503+ } else {
504+ path
505+ } ;
506+ self . inner . get ( path)
507+ }
508+ }
509+
510+ impl ContentProvider for MappingFileReader < ' _ > {
511+ fn get ( & mut self , path : & Path ) -> std:: io:: Result < Option < & str > > {
512+ self . get ( path) . map ( Some )
513+ }
514+ }
0 commit comments