@@ -11,8 +11,7 @@ use libtest_mimic::{Arguments, Trial};
11
11
pub fn runner ( requirements : & [ Requirements ] ) -> ExitCode {
12
12
let args = Arguments :: from_args ( ) ;
13
13
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) ;
16
15
17
16
let conclusion = libtest_mimic:: run ( & args, tests) ;
18
17
@@ -25,6 +24,43 @@ pub fn runner(requirements: &[Requirements]) -> ExitCode {
25
24
conclusion. exit_code ( )
26
25
}
27
26
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
+
28
64
#[ doc( hidden) ]
29
65
pub struct Requirements {
30
66
test : TestFn ,
@@ -49,6 +85,25 @@ impl Requirements {
49
85
}
50
86
}
51
87
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
+
52
107
/// Scans all files in a given directory, finds matching ones and generates a test descriptor
53
108
/// for each of them.
54
109
fn expand ( & self ) -> Vec < Trial > {
@@ -66,13 +121,7 @@ impl Requirements {
66
121
error
67
122
)
68
123
} ) {
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) )
76
125
} else {
77
126
None
78
127
}
0 commit comments