Skip to content

Commit 4b8b9aa

Browse files
committed
#42 Some refactoring
1 parent c736acc commit 4b8b9aa

File tree

1 file changed

+75
-82
lines changed

1 file changed

+75
-82
lines changed

src/lib.rs

+75-82
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,15 @@ use std::collections::HashMap;
192192

193193
use itertools::Itertools;
194194
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};
196196
use syn::spanned::Spanned;
197197

198198
use quote::quote;
199199

200200
use crate::parse::{
201201
fixture::FixtureInfo,
202+
rstest::{RsTestAttributes, RsTestData, RsTestInfo},
202203
testcase::TestCase,
203-
rstest::{RsTestAttributes, RsTestInfo, RsTestData},
204204
};
205205
use crate::refident::MaybeIdent;
206206
use crate::resolver::{arg_2_fixture, Resolver};
@@ -572,7 +572,7 @@ pub fn rstest(args: proc_macro::TokenStream,
572572
if errors.is_empty() {
573573
if info.data.has_list_values() {
574574
render_matrix_cases(test, info)
575-
} else if info.data.has_list_values() {
575+
} else if info.data.has_cases() {
576576
render_parametrize_cases(test, info)
577577
} else {
578578
render_single_case(test, info)
@@ -654,7 +654,7 @@ fn case_args_without_cases(params: &RsTestData) -> Errors {
654654
)
655655
}
656656

657-
fn errors_in_rstest(test: &ItemFn, info: &parse::rstest::RsTestInfo) -> TokenStream{
657+
fn errors_in_rstest(test: &ItemFn, info: &parse::rstest::RsTestInfo) -> TokenStream {
658658
missed_arguments_errors(test, info.data.items.iter())
659659
.chain(duplicate_arguments_errors(info.data.items.iter()))
660660
.chain(invalid_case_errors(&info.data))
@@ -745,6 +745,57 @@ fn render_parametrize_cases(test: ItemFn, info: RsTestInfo) -> TokenStream {
745745
render_cases(test, cases, attributes.into())
746746
}
747747

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+
748799
fn render_matrix_cases(test: ItemFn, info: parse::rstest::RsTestInfo) -> TokenStream {
749800
let parse::rstest::RsTestInfo { data, attributes, .. } = info;
750801
let span = test.sig.ident.span();
@@ -766,93 +817,34 @@ fn render_matrix_cases(test: ItemFn, info: parse::rstest::RsTestInfo) -> TokenSt
766817
}
767818
).collect();
768819

769-
let base_resolver = resolver::fixture_resolver(data.fixtures());
820+
let resolver = resolver::fixture_resolver(data.fixtures());
770821
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());
799823

800824
quote! {
801-
#[cfg(test)]
802-
#test
825+
#[cfg(test)]
826+
#test
803827

804-
#[cfg(test)]
805-
mod #fname {
828+
#[cfg(test)]
829+
mod #fname {
806830
use super::*;
807831

808-
#(#test_cases)*
832+
#wrapped_cases
809833
}
810834
}
811835
} 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)
848840
);
849841

850842
quote! {
851-
#[cfg(test)]
852-
#test
843+
#[cfg(test)]
844+
#test
853845

854-
#[cfg(test)]
855-
mod #fname {
846+
#[cfg(test)]
847+
mod #fname {
856848
use super::*;
857849

858850
#(#test_cases)*
@@ -1030,7 +1022,7 @@ mod render {
10301022
};
10311023

10321024
use crate::resolver::*;
1033-
use crate::test::{*, fixture, assert_eq};
1025+
use crate::test::{*, assert_eq, fixture};
10341026

10351027
use super::*;
10361028

@@ -1209,7 +1201,7 @@ mod render {
12091201

12101202
mod cases {
12111203
use crate::parse::{
1212-
rstest::{RsTestInfo, RsTestData, RsTestItem},
1204+
rstest::{RsTestData, RsTestInfo, RsTestItem},
12131205
testcase::TestCase,
12141206
};
12151207

@@ -1381,11 +1373,12 @@ mod render {
13811373
mod matrix_cases {
13821374
use unindent::Unindent;
13831375

1376+
use crate::parse::vlist::ValueList;
1377+
13841378
/// Should test matrix tests render without take in account MatrixInfo to RsTestInfo
1385-
/// transformation
1379+
/// transformation
13861380
13871381
use super::{*, assert_eq};
1388-
use crate::parse::vlist::ValueList;
13891382

13901383
fn into_rstest_data(item_fn: &ItemFn) -> RsTestData {
13911384
RsTestData {

0 commit comments

Comments
 (0)