@@ -10,7 +10,7 @@ use std::collections::HashMap;
1010use std:: fs;
1111use std:: fs:: File ;
1212use std:: io:: BufReader ;
13- use std:: path:: { Path , PathBuf } ;
13+ use std:: path:: { Component , Path , PathBuf } ;
1414use std:: str:: FromStr ;
1515
1616pub mod state;
@@ -94,13 +94,13 @@ fn main() -> Result<(), String> {
9494 print_state : false ,
9595 } ;
9696 let mut tests_result = TestExecutionResult :: new ( ) ;
97- for src_name in matches. get_many :: < PathBuf > ( "PATH" ) . unwrap ( ) {
98- let path = Path :: new ( src_name ) ;
99- assert ! ( path . exists ( ) , "data source does not exist" ) ;
100- if path . is_file ( ) {
101- run_vm_test_for_file ( & verbose_output, path , & mut tests_result) ;
102- } else if path . is_dir ( ) {
103- run_vm_test_for_dir ( & verbose_output, path , & mut tests_result) ;
97+ for src_path in matches. get_many :: < PathBuf > ( "PATH" ) . unwrap ( ) {
98+ assert ! ( src_path . exists ( ) , "data source does not exist" ) ;
99+
100+ if src_path . is_file ( ) {
101+ run_vm_test_for_file ( & verbose_output, src_path , & mut tests_result) ;
102+ } else if src_path . is_dir ( ) {
103+ run_vm_test_for_dir ( & verbose_output, src_path , & mut tests_result) ;
104104 }
105105 }
106106 println ! ( "\n TOTAL: {}" , tests_result. total) ;
@@ -124,27 +124,25 @@ fn main() -> Result<(), String> {
124124 print_state : matches. get_flag ( "print_state" ) ,
125125 } ;
126126 let mut tests_result = TestExecutionResult :: new ( ) ;
127- for src_name in matches. get_many :: < PathBuf > ( "PATH" ) . unwrap ( ) {
128- let path = Path :: new ( src_name) ;
129-
127+ for src_path in matches. get_many :: < PathBuf > ( "PATH" ) . unwrap ( ) {
130128 assert ! (
131- path . exists( ) ,
129+ src_path . exists( ) ,
132130 "data source does not exist: {}" ,
133- path . display( )
131+ src_path . display( )
134132 ) ;
135- if path . is_file ( ) {
133+ if src_path . is_file ( ) {
136134 run_test_for_file (
137135 spec. as_ref ( ) ,
138136 & verbose_output,
139- path ,
137+ src_path ,
140138 & mut tests_result,
141139 test_name,
142140 ) ;
143- } else if path . is_dir ( ) {
141+ } else if src_path . is_dir ( ) {
144142 run_test_for_dir (
145143 spec. as_ref ( ) ,
146144 & verbose_output,
147- path ,
145+ src_path ,
148146 & mut tests_result,
149147 test_name,
150148 ) ;
@@ -159,9 +157,9 @@ fn main() -> Result<(), String> {
159157 Ok ( ( ) )
160158}
161159
162- fn run_vm_test_for_dir (
160+ fn run_vm_test_for_dir < P : AsRef < Path > > (
163161 verbose_output : & VerboseOutput ,
164- dir_name : & Path ,
162+ dir_name : & P ,
165163 tests_result : & mut TestExecutionResult ,
166164) {
167165 for entry in fs:: read_dir ( dir_name) . unwrap ( ) {
@@ -173,26 +171,25 @@ fn run_vm_test_for_dir(
173171 }
174172 let path = entry. path ( ) ;
175173 if path. is_dir ( ) {
176- run_vm_test_for_dir ( verbose_output, path. as_path ( ) , tests_result) ;
174+ run_vm_test_for_dir ( verbose_output, & path, tests_result) ;
177175 } else {
178- run_vm_test_for_file ( verbose_output, path. as_path ( ) , tests_result) ;
176+ run_vm_test_for_file ( verbose_output, & path, tests_result) ;
179177 }
180178 }
181179}
182180
183- fn run_vm_test_for_file (
181+ fn run_vm_test_for_file < P : AsRef < Path > > (
184182 verbose_output : & VerboseOutput ,
185- file_name : & Path ,
183+ file_path : & P ,
186184 tests_result : & mut TestExecutionResult ,
187185) {
186+ let file_name = file_path. as_ref ( ) . to_str ( ) . unwrap ( ) ;
187+
188188 if verbose_output. verbose {
189- println ! (
190- "RUN for: {}" ,
191- short_test_file_name( file_name. to_str( ) . unwrap( ) )
192- ) ;
189+ println ! ( "RUN for: {}" , short_test_file_name( file_name) ) ;
193190 }
194191
195- let file = File :: open ( file_name ) . expect ( "Open file failed" ) ;
192+ let file = File :: open ( file_path ) . expect ( "Open file failed" ) ;
196193 let reader = BufReader :: new ( file) ;
197194 let test_suite = serde_json:: from_reader :: < _ , HashMap < String , VmTestCase > > ( reader)
198195 . expect ( "Parse test cases failed" ) ;
@@ -206,18 +203,15 @@ fn run_vm_test_for_file(
206203 println ! (
207204 "Failed:\t \t {} - {}\n " ,
208205 test_res. failed,
209- short_test_file_name( file_name. to_str ( ) . unwrap ( ) )
206+ short_test_file_name( file_name)
210207 ) ;
211208 } else if verbose_output. verbose_failed {
212- println ! (
213- "RUN for: {}" ,
214- short_test_file_name( file_name. to_str( ) . unwrap( ) )
215- ) ;
209+ println ! ( "RUN for: {}" , short_test_file_name( file_name) ) ;
216210 println ! ( "Tests count:\t {}" , test_res. total) ;
217211 println ! (
218212 "Failed:\t \t {} - {}\n " ,
219213 test_res. failed,
220- short_test_file_name( file_name. to_str ( ) . unwrap ( ) )
214+ short_test_file_name( file_name)
221215 ) ;
222216 }
223217 } else if verbose_output. verbose {
@@ -228,15 +222,15 @@ fn run_vm_test_for_file(
228222 }
229223}
230224
231- fn run_test_for_dir (
225+ fn run_test_for_dir < P : AsRef < Path > > (
232226 spec : Option < & Spec > ,
233227 verbose_output : & VerboseOutput ,
234- dir_name : & Path ,
228+ dir_name : & P ,
235229 tests_result : & mut TestExecutionResult ,
236230 test_name : Option < & String > ,
237231) {
238- if should_skip ( dir_name) {
239- println ! ( "Skipping the test case {}" , dir_name. display( ) ) ;
232+ if should_skip ( dir_name. as_ref ( ) ) {
233+ println ! ( "Skipping the test case {}" , dir_name. as_ref ( ) . display( ) ) ;
240234 return ;
241235 }
242236 for entry in fs:: read_dir ( dir_name) . unwrap ( ) {
@@ -248,45 +242,33 @@ fn run_test_for_dir(
248242 }
249243 let path = entry. path ( ) ;
250244 if path. is_dir ( ) {
251- run_test_for_dir (
252- spec,
253- verbose_output,
254- path. as_path ( ) ,
255- tests_result,
256- test_name,
257- ) ;
245+ run_test_for_dir ( spec, verbose_output, & path, tests_result, test_name) ;
258246 } else {
259- run_test_for_file (
260- spec,
261- verbose_output,
262- path. as_path ( ) ,
263- tests_result,
264- test_name,
265- ) ;
247+ run_test_for_file ( spec, verbose_output, & path, tests_result, test_name) ;
266248 }
267249 }
268250}
269251
270- fn run_test_for_file (
252+ fn run_test_for_file < P : AsRef < Path > > (
271253 spec : Option < & Spec > ,
272254 verbose_output : & VerboseOutput ,
273- file_name : & Path ,
255+ file_path : & P ,
274256 tests_result : & mut TestExecutionResult ,
275257 test_name : Option < & String > ,
276258) {
277- if should_skip ( file_name ) {
259+ if should_skip ( file_path . as_ref ( ) ) {
278260 if verbose_output. verbose {
279- println ! ( "Skipping the test case {}" , file_name . display( ) ) ;
261+ println ! ( "Skipping the test case {}" , file_path . as_ref ( ) . display( ) ) ;
280262 }
281263 return ;
282264 }
265+ let file_name = file_path. as_ref ( ) . to_str ( ) . unwrap ( ) ;
266+
283267 if verbose_output. verbose {
284- println ! (
285- "RUN for: {}" ,
286- short_test_file_name( file_name. to_str( ) . unwrap( ) )
287- ) ;
268+ println ! ( "RUN for: {}" , short_test_file_name( file_name) ) ;
288269 }
289- let file = File :: open ( file_name) . expect ( "Open file failed" ) ;
270+
271+ let file = File :: open ( file_path) . expect ( "Open file failed" ) ;
290272 let reader = BufReader :: new ( file) ;
291273
292274 let test_suite = serde_json:: from_reader :: < _ , HashMap < String , StateTestCase > > ( reader)
@@ -302,7 +284,7 @@ fn run_test_for_file(
302284 let test_config = TestConfig {
303285 verbose_output : verbose_output. clone ( ) ,
304286 spec : spec. cloned ( ) ,
305- file_name : file_name . to_path_buf ( ) ,
287+ file_name : file_path . as_ref ( ) . to_path_buf ( ) ,
306288 name,
307289 } ;
308290 let test_res = state:: test ( test_config, test) ;
@@ -313,18 +295,15 @@ fn run_test_for_file(
313295 println ! (
314296 "Failed:\t \t {} - {}\n " ,
315297 test_res. failed,
316- short_test_file_name( file_name. to_str ( ) . unwrap ( ) )
298+ short_test_file_name( file_name)
317299 ) ;
318300 } else if verbose_output. verbose_failed {
319- println ! (
320- "RUN for: {}" ,
321- short_test_file_name( file_name. to_str( ) . unwrap( ) )
322- ) ;
301+ println ! ( "RUN for: {}" , short_test_file_name( file_name) ) ;
323302 println ! ( "Tests count:\t {}" , test_res. total) ;
324303 println ! (
325304 "Failed:\t \t {} - {}\n " ,
326305 test_res. failed,
327- short_test_file_name( file_name. to_str ( ) . unwrap ( ) )
306+ short_test_file_name( file_name)
328307 ) ;
329308 }
330309 } else if verbose_output. verbose {
@@ -389,48 +368,44 @@ const SKIPPED_CASES: &[&str] = &[
389368/// - `path/and_file_stem` - check path and file name (without extension)
390369/// - `path/with/sub/path` - recursively check a path
391370fn should_skip ( path : & Path ) -> bool {
392- let matches = |case : & str | {
371+ let path_components: Vec < Component < ' _ > > = path. components ( ) . collect ( ) ;
372+ let path_len = path_components. len ( ) ;
373+ let path_stem = path. file_stem ( ) ;
374+
375+ SKIPPED_CASES . iter ( ) . any ( |case| {
393376 let case_path = Path :: new ( case) ;
394- let case_path_components: Vec < _ > = case_path. components ( ) . collect ( ) ;
395- let path_components: Vec < _ > = path. components ( ) . collect ( ) ;
396- let case_path_len = case_path_components. len ( ) ;
397- let path_len = path_components. len ( ) ;
377+ let case_components: Vec < Component < ' _ > > = case_path. components ( ) . collect ( ) ;
378+ let case_len = case_components. len ( ) ;
398379
399- // Check path length without a file name
400- if case_path_len > path_len {
380+ if case_len > path_len {
401381 return false ;
402382 }
403- // Check stem file name (without extension)
404- if let ( Some ( file_path_stem) , Some ( case_file_path_stem) ) =
405- ( path. file_stem ( ) , case_path. file_stem ( ) )
406- {
407- if file_path_stem == case_file_path_stem {
408- // If a case path contains only a file name
409- if case_path_len == 1 {
410- return true ;
383+
384+ // 1) Match by stem + optional parent suffix match
385+ if let ( Some ( ps) , Some ( cs) ) = ( path_stem, case_path. file_stem ( ) ) {
386+ if ps == cs {
387+ if case_len == 1 {
388+ return true ; // "just a filename (stem)" matches anywhere
411389 }
412- // Check sub path without file names
413- if case_path_len > 1
414- && path_len > 1
415- && case_path_components[ ..case_path_len - 1 ]
416- == path_components[ path_len - case_path_len..path_len - 1 ]
390+ // Compare parent components suffix (excluding the filename)
391+ if path_len >= case_len
392+ && case_components[ ..case_len - 1 ]
393+ == path_components[ path_len - case_len..path_len - 1 ]
417394 {
418395 return true ;
419396 }
420397 }
421398 }
422- // Check recursively path from the end without a file name
423- if case_path_len < path_len && path_len > 1 {
424- for i in 1 ..=path_len - case_path_len {
425- if case_path_components
426- == path_components[ path_len - case_path_len - i..path_len - i]
427- {
399+
400+ // 2) Match any contiguous component window (excluding filename semantics)
401+ if case_len < path_len {
402+ for start in 0 ..=( path_len - case_len) {
403+ if case_components == path_components[ start..start + case_len] {
428404 return true ;
429405 }
430406 }
431407 }
432- false
433- } ;
434408
435- SKIPPED_CASES . iter ( ) . any ( |case| matches ( case) )
409+ false
410+ } )
436411}
0 commit comments