@@ -11,8 +11,7 @@ use libtest_mimic::{Arguments, Trial};
1111pub fn runner ( requirements : & [ Requirements ] ) -> ExitCode {
1212 let args = Arguments :: from_args ( ) ;
1313
14- let mut tests: Vec < _ > = requirements. iter ( ) . flat_map ( |req| req. expand ( ) ) . collect ( ) ;
15- tests. sort_unstable_by ( |a, b| a. name ( ) . cmp ( b. name ( ) ) ) ;
14+ let tests = find_tests ( & args, requirements) ;
1615
1716 let conclusion = libtest_mimic:: run ( & args, tests) ;
1817
@@ -25,6 +24,43 @@ pub fn runner(requirements: &[Requirements]) -> ExitCode {
2524 conclusion. exit_code ( )
2625}
2726
27+ fn find_tests ( args : & Arguments , requirements : & [ Requirements ] ) -> Vec < Trial > {
28+ let tests: Vec < _ > = if let Some ( exact_filter) = exact_filter ( args) {
29+ let exact_tests: Vec < _ > = requirements
30+ . iter ( )
31+ . flat_map ( |req| req. exact ( exact_filter) )
32+ . collect ( ) ;
33+
34+ match exact_tests. len ( ) {
35+ 0 if is_nextest ( ) => {
36+ panic ! ( "Failed to find exact match for filter {exact_filter}" ) ;
37+ }
38+ len @ ( 2 ..) if is_nextest ( ) => {
39+ panic ! ( "Only expected one but found {len} exact matches for filter {exact_filter}" ) ;
40+ }
41+ _ => { }
42+ }
43+ exact_tests
44+ } else {
45+ let mut tests: Vec < _ > = requirements. iter ( ) . flat_map ( |req| req. expand ( ) ) . collect ( ) ;
46+ tests. sort_unstable_by ( |a, b| a. name ( ) . cmp ( b. name ( ) ) ) ;
47+ tests
48+ } ;
49+ tests
50+ }
51+
52+ fn is_nextest ( ) -> bool {
53+ std:: env:: var_os ( "NEXTEST" ) . is_some_and ( |val| val. eq ( "1" ) )
54+ }
55+
56+ fn exact_filter ( args : & Arguments ) -> Option < & str > {
57+ if args. exact && args. skip . is_empty ( ) {
58+ args. filter . as_deref ( )
59+ } else {
60+ None
61+ }
62+ }
63+
2864#[ doc( hidden) ]
2965pub struct Requirements {
3066 test : TestFn ,
@@ -49,6 +85,25 @@ impl Requirements {
4985 }
5086 }
5187
88+ fn trial ( & self , path : Utf8PathBuf ) -> Trial {
89+ let testfn = self . test ;
90+ let name = utils:: derive_test_name ( & self . root , & path, & self . test_name ) ;
91+ Trial :: test ( name, move || {
92+ testfn
93+ . call ( & path)
94+ . map_err ( |err| format ! ( "{:?}" , err) . into ( ) )
95+ } )
96+ }
97+
98+ fn exact ( & self , filter : & str ) -> Option < Trial > {
99+ let path = utils:: derive_test_path ( & self . root , filter, & self . test_name ) ?;
100+ if path. exists ( ) {
101+ Some ( self . trial ( path) )
102+ } else {
103+ None
104+ }
105+ }
106+
52107 /// Scans all files in a given directory, finds matching ones and generates a test descriptor
53108 /// for each of them.
54109 fn expand ( & self ) -> Vec < Trial > {
@@ -66,13 +121,7 @@ impl Requirements {
66121 error
67122 )
68123 } ) {
69- let testfn = self . test ;
70- let name = utils:: derive_test_name ( & self . root , & path, & self . test_name ) ;
71- Some ( Trial :: test ( name, move || {
72- testfn
73- . call ( & path)
74- . map_err ( |err| format ! ( "{:?}" , err) . into ( ) )
75- } ) )
124+ Some ( self . trial ( path) )
76125 } else {
77126 None
78127 }
0 commit comments