@@ -64,52 +64,33 @@ impl Deref for HashableRegex {
64
64
type TestFn < T > = fn ( & mut T , & Step ) -> ( ) ;
65
65
type TestRegexFn < T > = fn ( & mut T , & [ String ] , & Step ) -> ( ) ;
66
66
67
- pub struct TestCase < T : Default > {
68
- pub test : TestFn < T > ,
69
- }
70
-
71
- impl < T : Default > TestCase < T > {
72
- pub fn new ( test : TestFn < T > ) -> TestCase < T > {
73
- TestCase { test }
74
- }
75
- }
67
+ pub struct TestCase < T : Default > ( pub TestFn < T > ) ;
68
+ pub struct RegexTestCase < T : Default > ( pub TestRegexFn < T > ) ;
76
69
77
- pub struct RegexTestCase < ' a , T : ' a + Default > {
78
- pub test : TestRegexFn < T > ,
79
- _marker : std:: marker:: PhantomData < & ' a T > ,
80
- }
81
-
82
- impl < ' a , T : Default > RegexTestCase < ' a , T > {
83
- pub fn new ( test : TestRegexFn < T > ) -> RegexTestCase < ' a , T > {
84
- RegexTestCase {
85
- test,
86
- _marker : std:: marker:: PhantomData ,
87
- }
88
- }
89
- }
70
+ type TestBag < T > = HashMap < & ' static str , TestCase < T > > ;
71
+ type RegexBag < T > = HashMap < HashableRegex , RegexTestCase < T > > ;
90
72
91
73
#[ derive( Default ) ]
92
- pub struct Steps < ' s , T : ' s + Default > {
93
- pub given : HashMap < & ' static str , TestCase < T > > ,
94
- pub when : HashMap < & ' static str , TestCase < T > > ,
95
- pub then : HashMap < & ' static str , TestCase < T > > ,
96
- pub regex : RegexSteps < ' s , T > ,
74
+ pub struct Steps < T : Default > {
75
+ pub given : TestBag < T > ,
76
+ pub when : TestBag < T > ,
77
+ pub then : TestBag < T > ,
78
+ pub regex : RegexSteps < T > ,
97
79
}
98
80
99
81
#[ derive( Default ) ]
100
- pub struct RegexSteps < ' s , T : ' s + Default > {
101
- pub given : HashMap < HashableRegex , RegexTestCase < ' s , T > > ,
102
- pub when : HashMap < HashableRegex , RegexTestCase < ' s , T > > ,
103
- pub then : HashMap < HashableRegex , RegexTestCase < ' s , T > > ,
82
+ pub struct RegexSteps < T : Default > {
83
+ pub given : RegexBag < T > ,
84
+ pub when : RegexBag < T > ,
85
+ pub then : RegexBag < T > ,
104
86
}
105
87
106
88
pub enum TestCaseType < ' a , T >
107
89
where
108
- T : ' a ,
109
- T : Default ,
90
+ T : ' a + Default ,
110
91
{
111
92
Normal ( & ' a TestCase < T > ) ,
112
- Regex ( & ' a RegexTestCase < ' a , T > , Vec < String > ) ,
93
+ Regex ( & ' a RegexTestCase < T > , Vec < String > ) ,
113
94
}
114
95
115
96
pub enum TestResult {
@@ -120,74 +101,61 @@ pub enum TestResult {
120
101
Fail ( PanicDetails , Vec < u8 > ) ,
121
102
}
122
103
123
- impl < ' s , T : Default > Steps < ' s , T > {
124
- fn test_bag_for ( & self , ty : StepType ) -> & HashMap < & ' static str , TestCase < T > > {
104
+ impl < T : Default > Steps < T > {
105
+ fn test_bag_for ( & self , ty : StepType ) -> & TestBag < T > {
125
106
match ty {
126
107
StepType :: Given => & self . given ,
127
108
StepType :: When => & self . when ,
128
109
StepType :: Then => & self . then ,
129
110
}
130
111
}
131
112
132
- fn regex_bag_for < ' a > ( & ' a self , ty : StepType ) -> & HashMap < HashableRegex , RegexTestCase < ' a , T > > {
113
+ fn regex_bag_for ( & self , ty : StepType ) -> & RegexBag < T > {
133
114
match ty {
134
115
StepType :: Given => & self . regex . given ,
135
116
StepType :: When => & self . regex . when ,
136
117
StepType :: Then => & self . regex . then ,
137
118
}
138
119
}
139
120
140
- fn test_type ( & ' s self , step : & Step ) -> Option < TestCaseType < ' s , T > > {
141
- let test_bag = self . test_bag_for ( step. ty ) ;
142
-
143
- match test_bag. get ( & * step. value ) {
144
- Some ( v) => Some ( TestCaseType :: Normal ( v) ) ,
145
- None => {
146
- let regex_bag = self . regex_bag_for ( step. ty ) ;
147
-
148
- let result = regex_bag
149
- . iter ( )
150
- . find ( |( regex, _) | regex. is_match ( & step. value ) ) ;
121
+ fn test_type < ' a > ( & ' a self , step : & Step ) -> Option < TestCaseType < ' a , T > > {
122
+ if let Some ( t) = self . test_bag_for ( step. ty ) . get ( & * step. value ) {
123
+ return Some ( TestCaseType :: Normal ( t) ) ;
124
+ }
151
125
152
- match result {
153
- Some ( ( regex, tc) ) => {
154
- let matches = regex. 0 . captures ( & step. value ) . unwrap ( ) ;
155
- let matches: Vec < String > = matches
156
- . iter ( )
157
- . map ( |x| {
158
- x. map ( |s| s. as_str ( ) . to_string ( ) )
159
- . unwrap_or_else ( String :: new)
160
- } )
161
- . collect ( ) ;
162
- Some ( TestCaseType :: Regex ( tc, matches) )
163
- }
164
- None => None ,
165
- }
166
- }
126
+ if let Some ( ( regex, t) ) = self
127
+ . regex_bag_for ( step. ty )
128
+ . iter ( )
129
+ . find ( |( regex, _) | regex. is_match ( & step. value ) )
130
+ {
131
+ let matches = regex
132
+ . 0
133
+ . captures ( & step. value )
134
+ . unwrap ( )
135
+ . iter ( )
136
+ . map ( |match_| {
137
+ match_
138
+ . map ( |match_| match_. as_str ( ) . to_owned ( ) )
139
+ . unwrap_or_default ( )
140
+ } )
141
+ . collect ( ) ;
142
+
143
+ return Some ( TestCaseType :: Regex ( t, matches) ) ;
167
144
}
168
- }
169
145
170
- fn run_test_inner < ' a > (
171
- & ' s self ,
172
- world : & mut T ,
173
- test_type : TestCaseType < ' s , T > ,
174
- step : & ' a gherkin:: Step ,
175
- ) {
176
- match test_type {
177
- TestCaseType :: Normal ( t) => ( t. test ) ( world, & step) ,
178
- TestCaseType :: Regex ( t, ref c) => ( t. test ) ( world, c, & step) ,
179
- } ;
146
+ None
180
147
}
181
148
182
- fn run_test < ' a > (
183
- & ' s self ,
149
+ fn run_test (
150
+ & self ,
184
151
world : & mut T ,
185
- test_type : TestCaseType < ' s , T > ,
186
- step : & ' a Step ,
152
+ test_type : TestCaseType < ' _ , T > ,
153
+ step : & Step ,
187
154
suppress_output : bool ,
188
155
) -> TestResult {
189
- let test_result = PanicTrap :: run ( suppress_output, move || {
190
- self . run_test_inner ( world, test_type, & step)
156
+ let test_result = PanicTrap :: run ( suppress_output, move || match test_type {
157
+ TestCaseType :: Normal ( t) => ( t. 0 ) ( world, & step) ,
158
+ TestCaseType :: Regex ( t, ref c) => ( t. 0 ) ( world, c, & step) ,
191
159
} ) ;
192
160
193
161
match test_result. result {
@@ -203,13 +171,13 @@ impl<'s, T: Default> Steps<'s, T> {
203
171
}
204
172
205
173
#[ allow( clippy:: too_many_arguments) ]
206
- fn run_scenario < ' a > (
207
- & ' s self ,
208
- feature : & ' a gherkin:: Feature ,
209
- rule : Option < & ' a gherkin:: Rule > ,
210
- scenario : & ' a gherkin:: Scenario ,
211
- before_fns : & ' a Option < & [ HelperFn ] > ,
212
- after_fns : & ' a Option < & [ HelperFn ] > ,
174
+ fn run_scenario (
175
+ & self ,
176
+ feature : & gherkin:: Feature ,
177
+ rule : Option < & gherkin:: Rule > ,
178
+ scenario : & gherkin:: Scenario ,
179
+ before_fns : & Option < & [ HelperFn ] > ,
180
+ after_fns : & Option < & [ HelperFn ] > ,
213
181
suppress_output : bool ,
214
182
output : & mut impl OutputVisitor ,
215
183
) -> bool {
@@ -221,8 +189,6 @@ impl<'s, T: Default> Steps<'s, T> {
221
189
}
222
190
}
223
191
224
- let mut is_success = true ;
225
-
226
192
let mut world = {
227
193
let panic_trap = PanicTrap :: run ( suppress_output, T :: default) ;
228
194
match panic_trap. result {
@@ -241,20 +207,17 @@ impl<'s, T: Default> Steps<'s, T> {
241
207
}
242
208
} ;
243
209
244
- let mut steps: Vec < & ' a Step > = vec ! [ ] ;
245
- if let Some ( ref bg) = & feature. background {
246
- for s in & bg. steps {
247
- steps. push ( & s) ;
248
- }
249
- }
250
-
251
- for s in & scenario. steps {
252
- steps. push ( & s) ;
253
- }
254
-
210
+ let mut is_success = true ;
255
211
let mut is_skipping = false ;
256
212
257
- for step in steps. iter ( ) {
213
+ let steps = feature
214
+ . background
215
+ . iter ( )
216
+ . map ( |bg| bg. steps . iter ( ) )
217
+ . flatten ( )
218
+ . chain ( scenario. steps . iter ( ) ) ;
219
+
220
+ for step in steps {
258
221
output. visit_step ( rule, & scenario, & step) ;
259
222
260
223
let test_type = match self . test_type ( & step) {
@@ -300,10 +263,10 @@ impl<'s, T: Default> Steps<'s, T> {
300
263
}
301
264
302
265
#[ allow( clippy:: too_many_arguments) ]
303
- fn run_scenarios < ' a > (
304
- & ' s self ,
305
- feature : & ' a gherkin:: Feature ,
306
- rule : Option < & ' a gherkin:: Rule > ,
266
+ fn run_scenarios (
267
+ & self ,
268
+ feature : & gherkin:: Feature ,
269
+ rule : Option < & gherkin:: Rule > ,
307
270
scenarios : & [ gherkin:: Scenario ] ,
308
271
before_fns : Option < & [ HelperFn ] > ,
309
272
after_fns : Option < & [ HelperFn ] > ,
@@ -347,7 +310,7 @@ impl<'s, T: Default> Steps<'s, T> {
347
310
}
348
311
349
312
pub fn run (
350
- & ' s self ,
313
+ & self ,
351
314
feature_files : Vec < PathBuf > ,
352
315
before_fns : Option < & [ HelperFn ] > ,
353
316
after_fns : Option < & [ HelperFn ] > ,
@@ -639,7 +602,7 @@ macro_rules! steps {
639
602
) => {
640
603
$tests. regex. $ty. insert(
641
604
$crate:: HashableRegex ( $crate:: regex:: Regex :: new( $name) . expect( & format!( "{} is a valid regex" , $name) ) ) ,
642
- $crate:: RegexTestCase :: new ( $body) ) ;
605
+ $crate:: RegexTestCase ( $body) ) ;
643
606
} ;
644
607
645
608
(
@@ -648,7 +611,7 @@ macro_rules! steps {
648
611
) => {
649
612
$tests. regex. $ty. insert(
650
613
$crate:: HashableRegex ( $crate:: regex:: Regex :: new( $name) . expect( & format!( "{} is a valid regex" , $name) ) ) ,
651
- $crate:: RegexTestCase :: new ( $body) ) ;
614
+ $crate:: RegexTestCase ( $body) ) ;
652
615
653
616
steps!( @gather_steps, $worldtype, $tests, $( $items ) * ) ;
654
617
} ;
@@ -659,7 +622,7 @@ macro_rules! steps {
659
622
) => {
660
623
$tests. regex. $ty. insert(
661
624
$crate:: HashableRegex ( $crate:: regex:: Regex :: new( $name) . expect( & format!( "{} is a valid regex" , $name) ) ) ,
662
- $crate:: RegexTestCase :: new ( |world: & mut $worldtype, matches, step| {
625
+ $crate:: RegexTestCase ( |world: & mut $worldtype, matches, step| {
663
626
let closure: Box <Fn ( & mut $worldtype, $( $arg_type, ) * & $crate:: gherkin:: Step ) -> ( ) > = Box :: new( $body) ;
664
627
let mut matches = matches. into_iter( ) . enumerate( ) ;
665
628
@@ -680,7 +643,7 @@ macro_rules! steps {
680
643
) => {
681
644
$tests. regex. $ty. insert(
682
645
$crate:: HashableRegex ( $crate:: regex:: Regex :: new( $name) . expect( & format!( "{} is a valid regex" , $name) ) ) ,
683
- $crate:: RegexTestCase :: new ( |world: & mut $worldtype, matches, step| {
646
+ $crate:: RegexTestCase ( |world: & mut $worldtype, matches, step| {
684
647
let closure: Box <Fn ( & mut $worldtype, $( $arg_type, ) * & $crate:: gherkin:: Step ) -> ( ) > = Box :: new( $body) ;
685
648
let mut matches = matches. into_iter( ) . enumerate( ) . skip( 1 ) ;
686
649
@@ -701,14 +664,14 @@ macro_rules! steps {
701
664
@gather_steps, $worldtype: path, $tests: tt,
702
665
$ty: ident $name: tt $body: expr;
703
666
) => {
704
- $tests. $ty. insert( $name, $crate:: TestCase :: new ( $body) ) ;
667
+ $tests. $ty. insert( $name, $crate:: TestCase ( $body) ) ;
705
668
} ;
706
669
707
670
(
708
671
@gather_steps, $worldtype: path, $tests: tt,
709
672
$ty: ident $name: tt $body: expr; $( $items: tt ) *
710
673
) => {
711
- $tests. $ty. insert( $name, $crate:: TestCase :: new ( $body) ) ;
674
+ $tests. $ty. insert( $name, $crate:: TestCase ( $body) ) ;
712
675
713
676
steps!( @gather_steps, $worldtype, $tests, $( $items ) * ) ;
714
677
} ;
@@ -717,11 +680,11 @@ macro_rules! steps {
717
680
$worldtype: path => { $( $items: tt ) * }
718
681
) => {
719
682
#[ allow( unused_imports) ]
720
- pub fn steps< ' a> ( ) -> $crate:: Steps <' a , $worldtype> {
683
+ pub fn steps( ) -> $crate:: Steps <$worldtype> {
721
684
use std:: path:: Path ;
722
685
use std:: process;
723
686
724
- let mut tests: $crate:: Steps <' a , $worldtype> = $crate :: Steps :: default ( ) ;
687
+ let mut tests: $crate:: Steps <$worldtype> = Default :: default ( ) ;
725
688
steps!( @gather_steps, $worldtype, tests, $( $items ) * ) ;
726
689
tests
727
690
}
0 commit comments