@@ -45,34 +45,47 @@ pub use snapbox::data::DataFormat;
45
45
pub use snapbox:: Data ;
46
46
47
47
/// [`Harness`] for discovering test inputs and asserting against snapshot files
48
- pub struct Harness < S , T > {
48
+ pub struct Harness < S , T , I , E > {
49
49
root : std:: path:: PathBuf ,
50
50
overrides : Option < ignore:: overrides:: Override > ,
51
51
setup : S ,
52
52
test : T ,
53
53
config : snapbox:: Assert ,
54
+ test_output : std:: marker:: PhantomData < I > ,
55
+ test_error : std:: marker:: PhantomData < E > ,
54
56
}
55
57
56
- impl < S , T , I , E > Harness < S , T >
58
+ impl < S , T , I , E > Harness < S , T , I , E >
57
59
where
60
+ S : Setup + Send + Sync + ' static ,
61
+ T : Test < I , E > + Clone + Send + Sync + ' static ,
58
62
I : std:: fmt:: Display ,
59
63
E : std:: fmt:: Display ,
60
- S : Fn ( std:: path:: PathBuf ) -> Case + Send + Sync + ' static ,
61
- T : Fn ( & std:: path:: Path ) -> Result < I , E > + Send + Sync + ' static + Clone ,
62
64
{
63
65
/// Specify where the test scenarios
64
66
///
65
67
/// - `input_root`: where to find the files. See [`Self::select`] for restricting what files
66
68
/// are considered
67
69
/// - `setup`: Given a path, choose the test name and the output location
68
70
/// - `test`: Given a path, return the actual output value
71
+ ///
72
+ /// By default filters are applied, including:
73
+ /// - `...` is a line-wildcard when on a line by itself
74
+ /// - `[..]` is a character-wildcard when inside a line
75
+ /// - `[EXE]` matches `.exe` on Windows
76
+ /// - `\` to `/`
77
+ /// - Newlines
78
+ ///
79
+ /// To limit this to newline normalization for text, have [`Setup`] call [`Data::raw`][snapbox::Data::raw] on `expected`.
69
80
pub fn new ( input_root : impl Into < std:: path:: PathBuf > , setup : S , test : T ) -> Self {
70
81
Self {
71
82
root : input_root. into ( ) ,
72
83
overrides : None ,
73
84
setup,
74
85
test,
75
86
config : snapbox:: Assert :: new ( ) . action_env ( snapbox:: assert:: DEFAULT_ACTION_ENV ) ,
87
+ test_output : Default :: default ( ) ,
88
+ test_error : Default :: default ( ) ,
76
89
}
77
90
}
78
91
@@ -120,17 +133,17 @@ where
120
133
let tests: Vec < _ > = tests
121
134
. into_iter ( )
122
135
. map ( |path| {
123
- let case = ( self . setup ) ( path) ;
136
+ let case = self . setup . setup ( path) ;
124
137
assert ! (
125
138
case. expected. source( ) . map( |s| s. is_path( ) ) . unwrap_or( false ) ,
126
139
"`Case::expected` must be from a file"
127
140
) ;
128
141
let test = self . test . clone ( ) ;
129
142
let config = shared_config. clone ( ) ;
130
143
Trial :: test ( case. name . clone ( ) , move || {
131
- let actual = ( test) ( & case. fixture ) ?;
144
+ let actual = test. run ( & case. fixture ) ?;
132
145
let actual = actual. to_string ( ) ;
133
- let actual = crate :: Data :: text ( actual) ;
146
+ let actual = snapbox :: Data :: text ( actual) ;
134
147
config. try_eq ( Some ( & case. name ) , actual, case. expected . clone ( ) ) ?;
135
148
Ok ( ( ) )
136
149
} )
@@ -145,9 +158,41 @@ where
145
158
}
146
159
}
147
160
148
- /// A test case enumerated by the [`Harness`] with data from the `setup` function
149
- ///
150
- /// See [`harness`][crate] for more details
161
+ /// Function signature for generating a test [`Case`] from a path fixture
162
+ pub trait Setup {
163
+ fn setup ( & self , fixture : std:: path:: PathBuf ) -> Case ;
164
+ }
165
+
166
+ impl < F > Setup for F
167
+ where
168
+ F : Fn ( std:: path:: PathBuf ) -> Case ,
169
+ {
170
+ fn setup ( & self , fixture : std:: path:: PathBuf ) -> Case {
171
+ ( self ) ( fixture)
172
+ }
173
+ }
174
+
175
+ /// Function signature for running a test [`Case`]
176
+ pub trait Test < S , E >
177
+ where
178
+ S : std:: fmt:: Display ,
179
+ E : std:: fmt:: Display ,
180
+ {
181
+ fn run ( & self , fixture : & std:: path:: Path ) -> Result < S , E > ;
182
+ }
183
+
184
+ impl < F , S , E > Test < S , E > for F
185
+ where
186
+ F : Fn ( & std:: path:: Path ) -> Result < S , E > ,
187
+ S : std:: fmt:: Display ,
188
+ E : std:: fmt:: Display ,
189
+ {
190
+ fn run ( & self , fixture : & std:: path:: Path ) -> Result < S , E > {
191
+ ( self ) ( fixture)
192
+ }
193
+ }
194
+
195
+ /// A test case enumerated by the [`Harness`] with data from the [`Setup`] function
151
196
pub struct Case {
152
197
/// Display name
153
198
pub name : String ,
0 commit comments