@@ -192,15 +192,15 @@ use std::collections::HashMap;
192
192
193
193
use itertools:: Itertools ;
194
194
use proc_macro2:: { Span , TokenStream } ;
195
- use syn:: { FnArg , Ident , ItemFn , parse_macro_input, parse_quote, Stmt , ReturnType , Generics } ;
195
+ use syn:: { FnArg , Generics , Ident , ItemFn , parse_macro_input, parse_quote, ReturnType , Stmt } ;
196
196
use syn:: spanned:: Spanned ;
197
197
198
198
use quote:: quote;
199
199
200
200
use crate :: parse:: {
201
201
fixture:: FixtureInfo ,
202
+ rstest:: { RsTestAttributes , RsTestData , RsTestInfo } ,
202
203
testcase:: TestCase ,
203
- rstest:: { RsTestAttributes , RsTestInfo , RsTestData } ,
204
204
} ;
205
205
use crate :: refident:: MaybeIdent ;
206
206
use crate :: resolver:: { arg_2_fixture, Resolver } ;
@@ -572,7 +572,7 @@ pub fn rstest(args: proc_macro::TokenStream,
572
572
if errors. is_empty ( ) {
573
573
if info. data . has_list_values ( ) {
574
574
render_matrix_cases ( test, info)
575
- } else if info. data . has_list_values ( ) {
575
+ } else if info. data . has_cases ( ) {
576
576
render_parametrize_cases ( test, info)
577
577
} else {
578
578
render_single_case ( test, info)
@@ -654,7 +654,7 @@ fn case_args_without_cases(params: &RsTestData) -> Errors {
654
654
)
655
655
}
656
656
657
- fn errors_in_rstest ( test : & ItemFn , info : & parse:: rstest:: RsTestInfo ) -> TokenStream {
657
+ fn errors_in_rstest ( test : & ItemFn , info : & parse:: rstest:: RsTestInfo ) -> TokenStream {
658
658
missed_arguments_errors ( test, info. data . items . iter ( ) )
659
659
. chain ( duplicate_arguments_errors ( info. data . items . iter ( ) ) )
660
660
. chain ( invalid_case_errors ( & info. data ) )
@@ -745,6 +745,57 @@ fn render_parametrize_cases(test: ItemFn, info: RsTestInfo) -> TokenStream {
745
745
render_cases ( test, cases, attributes. into ( ) )
746
746
}
747
747
748
+ fn render_inner_matrix_cases < ' a > ( test : & ItemFn , attributes : & RsTestAttributes , resolver : & impl Resolver ,
749
+ list_values : impl Iterator < Item =& ' a crate :: parse:: vlist:: ValueList > ) -> TokenStream {
750
+ let test_function_span = test. sig . ident . span ( ) ;
751
+ // Steps:
752
+ // 1. pack data P=(ident, expr, (pos, max_len)) in one iterator for each variable
753
+ // 2. do a cartesian product of iterators to build all cases (every case is a vector of P)
754
+ // 3. format case by packed data vector
755
+ let test_cases = list_values
756
+ . map ( |group|
757
+ group. values . iter ( )
758
+ . enumerate ( )
759
+ . map ( move |( pos, expr) | ( & group. arg , expr, ( pos, group. values . len ( ) ) ) )
760
+ )
761
+ . multi_cartesian_product ( )
762
+ . map ( |c| {
763
+ let args_indexes = c. iter ( )
764
+ . map ( |( _, _, ( index, max) ) |
765
+ format ! ( "{:0len$}" , index + 1 , len = max. display_len( ) )
766
+ )
767
+ . collect :: < Vec < _ > > ( )
768
+ . join ( "_" ) ;
769
+ let name = format ! ( "case_{}" , args_indexes) ;
770
+ let resolver_case = c. into_iter ( )
771
+ . map ( |( a, e, _) | ( a. to_string ( ) , e) )
772
+ . collect :: < HashMap < _ , _ > > ( ) ;
773
+ TestCaseRender :: new ( Ident :: new ( & name, test_function_span) ,
774
+ ( resolver_case, resolver) )
775
+ }
776
+ ) ;
777
+
778
+ let test_cases = test_cases. map ( |test_case| test_case. render ( test, attributes) ) ;
779
+
780
+ quote ! { #( #test_cases) * }
781
+ }
782
+
783
+ trait WrapByModule {
784
+ fn wrap_by_mod ( & self , mod_name : & Ident ) -> TokenStream ;
785
+ }
786
+
787
+ impl < T : quote:: ToTokens > WrapByModule for T {
788
+ fn wrap_by_mod ( & self , mod_name : & Ident ) -> TokenStream {
789
+ quote ! {
790
+ mod #mod_name {
791
+ use super :: * ;
792
+
793
+ #self
794
+ }
795
+ }
796
+ }
797
+ }
798
+
748
799
fn render_matrix_cases ( test : ItemFn , info : parse:: rstest:: RsTestInfo ) -> TokenStream {
749
800
let parse:: rstest:: RsTestInfo { data, attributes, .. } = info;
750
801
let span = test. sig . ident . span ( ) ;
@@ -766,93 +817,34 @@ fn render_matrix_cases(test: ItemFn, info: parse::rstest::RsTestInfo) -> TokenSt
766
817
}
767
818
) . collect ( ) ;
768
819
769
- let base_resolver = resolver:: fixture_resolver ( data. fixtures ( ) ) ;
820
+ let resolver = resolver:: fixture_resolver ( data. fixtures ( ) ) ;
770
821
if cases. is_empty ( ) {
771
- // Steps:
772
- // 1. pack data P=(ident, expr, (pos, max_len)) in one iterator for each variable
773
- // 2. do a cartesian product of iterators to build all cases (every case is a vector of P)
774
- // 3. format case by packed data vector
775
- let test_cases = data. list_values ( )
776
- . map ( |group|
777
- group. values . iter ( )
778
- . enumerate ( )
779
- . map ( move |( pos, expr) | ( & group. arg , expr, ( pos, group. values . len ( ) ) ) )
780
- )
781
- . multi_cartesian_product ( )
782
- . map ( |c| {
783
- let args_indexes = c. iter ( )
784
- . map ( |( _, _, ( index, max) ) |
785
- format ! ( "{:0len$}" , index + 1 , len = max. display_len( ) )
786
- )
787
- . collect :: < Vec < _ > > ( )
788
- . join ( "_" ) ;
789
- let name = format ! ( "case_{}" , args_indexes) ;
790
- let resolver_case = c. into_iter ( )
791
- . map ( |( a, e, _) | ( a. to_string ( ) , e) )
792
- . collect :: < HashMap < _ , _ > > ( ) ;
793
- TestCaseRender :: new ( Ident :: new ( & name, span) ,
794
- ( resolver_case, & base_resolver) )
795
- }
796
- ) ;
797
-
798
- let test_cases = test_cases. map ( |test_case| test_case. render ( & test, & attributes) ) ;
822
+ let wrapped_cases = render_inner_matrix_cases ( & test, & attributes, & resolver, data. list_values ( ) ) ;
799
823
800
824
quote ! {
801
- #[ cfg( test) ]
802
- #test
825
+ #[ cfg( test) ]
826
+ #test
803
827
804
- #[ cfg( test) ]
805
- mod #fname {
828
+ #[ cfg( test) ]
829
+ mod #fname {
806
830
use super :: * ;
807
831
808
- #( #test_cases ) *
832
+ #wrapped_cases
809
833
}
810
834
}
811
835
} else {
812
-
813
- let test_cases = cases. into_iter ( ) . map (
814
- |( resolver, case_name) | {
815
- let resolver = ( resolver, & base_resolver) ;
816
- let test_cases = data. list_values ( )
817
- . map ( |group|
818
- group. values . iter ( )
819
- . enumerate ( )
820
- . map ( move |( pos, expr) | ( & group. arg , expr, ( pos, group. values . len ( ) ) ) )
821
- )
822
- . multi_cartesian_product ( )
823
- . map ( |c| {
824
- let args_indexes = c. iter ( )
825
- . map ( |( _, _, ( index, max) ) |
826
- format ! ( "{:0len$}" , index + 1 , len = max. display_len( ) )
827
- )
828
- . collect :: < Vec < _ > > ( )
829
- . join ( "_" ) ;
830
- let name = format ! ( "case_{}" , args_indexes) ;
831
- let resolver_case = c. into_iter ( )
832
- . map ( |( a, e, _) | ( a. to_string ( ) , e) )
833
- . collect :: < HashMap < _ , _ > > ( ) ;
834
- TestCaseRender :: new ( Ident :: new ( & name, span) ,
835
- ( resolver_case, & resolver)
836
- )
837
- }
838
- )
839
- . map ( |test_case| test_case. render ( & test, & attributes) ) ;
840
- quote ! {
841
- mod #case_name {
842
- use super :: * ;
843
-
844
- #( #test_cases) *
845
- }
846
- }
847
- }
836
+ let test_cases = cases. into_iter ( ) . map (
837
+ |( case_resolver, case_name) |
838
+ render_inner_matrix_cases ( & test, & attributes, & ( case_resolver, & resolver) , data. list_values ( ) )
839
+ . wrap_by_mod ( & case_name)
848
840
) ;
849
841
850
842
quote ! {
851
- #[ cfg( test) ]
852
- #test
843
+ #[ cfg( test) ]
844
+ #test
853
845
854
- #[ cfg( test) ]
855
- mod #fname {
846
+ #[ cfg( test) ]
847
+ mod #fname {
856
848
use super :: * ;
857
849
858
850
#( #test_cases) *
@@ -1030,7 +1022,7 @@ mod render {
1030
1022
} ;
1031
1023
1032
1024
use crate :: resolver:: * ;
1033
- use crate :: test:: { * , fixture , assert_eq } ;
1025
+ use crate :: test:: { * , assert_eq , fixture } ;
1034
1026
1035
1027
use super :: * ;
1036
1028
@@ -1209,7 +1201,7 @@ mod render {
1209
1201
1210
1202
mod cases {
1211
1203
use crate :: parse:: {
1212
- rstest:: { RsTestInfo , RsTestData , RsTestItem } ,
1204
+ rstest:: { RsTestData , RsTestInfo , RsTestItem } ,
1213
1205
testcase:: TestCase ,
1214
1206
} ;
1215
1207
@@ -1381,11 +1373,12 @@ mod render {
1381
1373
mod matrix_cases {
1382
1374
use unindent:: Unindent ;
1383
1375
1376
+ use crate :: parse:: vlist:: ValueList ;
1377
+
1384
1378
/// Should test matrix tests render without take in account MatrixInfo to RsTestInfo
1385
- /// transformation
1379
+ /// transformation
1386
1380
1387
1381
use super :: { * , assert_eq} ;
1388
- use crate :: parse:: vlist:: ValueList ;
1389
1382
1390
1383
fn into_rstest_data ( item_fn : & ItemFn ) -> RsTestData {
1391
1384
RsTestData {
0 commit comments