Skip to content

Commit 6e7607d

Browse files
committed
#42 matrix routed by rstest. Complete parsing test. Some little refactoring.
1 parent 00f3331 commit 6e7607d

File tree

6 files changed

+217
-396
lines changed

6 files changed

+217
-396
lines changed

src/lib.rs

+53-77
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,8 @@ pub fn rstest(args: proc_macro::TokenStream,
572572
if errors.is_empty() {
573573
if info.data.has_cases() {
574574
render_parametrize_cases(test, info)
575+
} else if info.data.has_list_values() {
576+
render_matrix_cases(test, info)
575577
} else {
576578
render_single_case(test, info)
577579
}
@@ -602,7 +604,7 @@ fn missed_arguments_errors<'a, I: MaybeIdent + Spanned + 'a>(test: &'a ItemFn, a
602604
.filter_map(|it| it.maybe_ident().map(|ident| (it, ident)))
603605
.filter(move |(_, ident)| !fn_args_has_ident(test, ident))
604606
.map(|(missed, ident)| syn::Error::new(missed.span(),
605-
&format!("Missed argument: '{}' should be a test function argument.", ident),
607+
&format!("Missed argument: '{}' should be a test function argument.", ident),
606608
))
607609
)
608610
}
@@ -644,22 +646,14 @@ fn invalid_case_errors(params: &RsTestData) -> Errors {
644646
fn case_args_without_cases(params: &RsTestData) -> Errors {
645647
if !params.has_cases() {
646648
return Box::new(params.case_args().map(|a|
647-
syn::Error::new(a.span(), "No cases for this argument."))
649+
syn::Error::new(a.span(), "No cases for this argument."))
648650
);
649651
}
650652
Box::new(
651653
std::iter::empty()
652654
)
653655
}
654656

655-
fn errors_in_matrix(test: &ItemFn, info: &parse::matrix::MatrixInfo) -> TokenStream {
656-
missed_arguments_errors(test, info.args.list_values())
657-
.chain(missed_arguments_errors(test, info.args.fixtures()))
658-
.chain(duplicate_arguments_errors(info.args.items.iter()))
659-
.map(|e| e.to_compile_error())
660-
.collect()
661-
}
662-
663657
fn errors_in_rstest(test: &ItemFn, info: &parse::rstest::RsTestInfo) -> TokenStream{
664658
missed_arguments_errors(test, info.data.items.iter())
665659
.chain(duplicate_arguments_errors(info.data.items.iter()))
@@ -751,15 +745,15 @@ fn render_parametrize_cases(test: ItemFn, info: RsTestInfo) -> TokenStream {
751745
render_cases(test, cases, attributes.into())
752746
}
753747

754-
fn render_matrix_cases(test: ItemFn, params: parse::matrix::MatrixInfo) -> TokenStream {
755-
let parse::matrix::MatrixInfo { args, attributes, .. } = params;
748+
fn render_matrix_cases(test: ItemFn, info: parse::rstest::RsTestInfo) -> TokenStream {
749+
let parse::rstest::RsTestInfo { data, attributes, .. } = info;
756750
let span = test.sig.ident.span();
757751

758752
// Steps:
759753
// 1. pack data P=(ident, expr, (pos, max_len)) in one iterator for each variable
760754
// 2. do a cartesian product of iterators to build all cases (every case is a vector of P)
761755
// 3. format case by packed data vector
762-
let cases = args.list_values()
756+
let cases = data.list_values()
763757
.map(|group|
764758
group.values.iter()
765759
.enumerate()
@@ -774,7 +768,7 @@ fn render_matrix_cases(test: ItemFn, params: parse::matrix::MatrixInfo) -> Token
774768
.collect::<Vec<_>>()
775769
.join("_");
776770
let name = format!("case_{}", args_indexes);
777-
let resolver_fixture = resolver::fixture_resolver(args.fixtures());
771+
let resolver_fixture = resolver::fixture_resolver(data.fixtures());
778772
let resolver_case = c.into_iter()
779773
.map(|(a, e, _)| (a.to_string(), e))
780774
.collect::<HashMap<_, _>>();
@@ -783,7 +777,7 @@ fn render_matrix_cases(test: ItemFn, params: parse::matrix::MatrixInfo) -> Token
783777
}
784778
);
785779

786-
render_cases(test, cases, attributes.into())
780+
render_cases(test, cases, attributes)
787781
}
788782

789783
/// Write table-based tests: you must indicate the arguments that you want use in your cases
@@ -944,16 +938,7 @@ pub fn rstest_parametrize(args: proc_macro::TokenStream, input: proc_macro::Toke
944938
pub fn rstest_matrix(args: proc_macro::TokenStream, input: proc_macro::TokenStream)
945939
-> proc_macro::TokenStream
946940
{
947-
let info = parse_macro_input!(args as parse::matrix::MatrixInfo);
948-
let test = parse_macro_input!(input as ItemFn);
949-
950-
let errors = errors_in_matrix(&test, &info);
951-
952-
if errors.is_empty() {
953-
render_matrix_cases(test, info).into()
954-
} else {
955-
errors
956-
}.into()
941+
rstest(args, input)
957942
}
958943

959944
#[cfg(test)]
@@ -1130,35 +1115,31 @@ mod render {
11301115

11311116
use crate::parse::{
11321117
rstest::{RsTestInfo, RsTestData, RsTestItem},
1133-
testcase::TestCase
1118+
testcase::TestCase,
11341119
};
11351120

11361121
use super::{*, assert_eq};
11371122

1138-
impl<'a> From<&'a ItemFn> for RsTestData {
1139-
fn from(item_fn: &'a ItemFn) -> Self {
1140-
RsTestData {
1141-
items: fn_args_idents(item_fn)
1142-
.cloned()
1143-
.map(RsTestItem::CaseArgName)
1144-
.collect(),
1145-
}
1123+
fn into_rstest_data(item_fn: &ItemFn) -> RsTestData {
1124+
RsTestData {
1125+
items: fn_args_idents(item_fn)
1126+
.cloned()
1127+
.map(RsTestItem::CaseArgName)
1128+
.collect(),
11461129
}
11471130
}
11481131

1149-
impl<'a> From<&'a ItemFn> for RsTestInfo {
1150-
fn from(item_fn: &'a ItemFn) -> Self {
1151-
RsTestInfo {
1152-
data: item_fn.into(),
1153-
attributes: Default::default(),
1154-
}
1132+
fn into_rstest_info(item_fn: &ItemFn) -> RsTestInfo {
1133+
RsTestInfo {
1134+
data: into_rstest_data(item_fn),
1135+
attributes: Default::default(),
11551136
}
11561137
}
11571138

11581139
#[test]
11591140
fn should_create_a_module_named_as_test_function() {
11601141
let item_fn = parse_str::<ItemFn>("fn should_be_the_module_name(mut fix: String) {}").unwrap();
1161-
let info = (&item_fn).into();
1142+
let info = into_rstest_info(&item_fn);
11621143
let tokens = render_parametrize_cases(item_fn.clone(), info);
11631144

11641145
let output = TestsGroup::from(tokens);
@@ -1171,7 +1152,7 @@ mod render {
11711152
let item_fn = parse_str::<ItemFn>(
11721153
r#"fn should_be_the_module_name(mut fix: String) { println!("user code") }"#
11731154
).unwrap();
1174-
let info = (&item_fn).into();
1155+
let info = into_rstest_info(&item_fn);
11751156
let tokens = render_parametrize_cases(item_fn.clone(), info);
11761157

11771158
let mut output = TestsGroup::from(tokens);
@@ -1185,7 +1166,7 @@ mod render {
11851166
let item_fn = parse_str::<ItemFn>(
11861167
r#"fn should_be_the_module_name(mut fix: String) { println!("user code") }"#
11871168
).unwrap();
1188-
let info = (&item_fn).into();
1169+
let info = into_rstest_info(&item_fn);
11891170
let tokens = render_parametrize_cases(item_fn.clone(), info);
11901171

11911172
let output = TestsGroup::from(tokens);
@@ -1203,7 +1184,7 @@ mod render {
12031184
let item_fn = parse_str::<ItemFn>(
12041185
r#"fn should_be_the_module_name(mut fix: String) { println!("user code") }"#
12051186
).unwrap();
1206-
let info = (&item_fn).into();
1187+
let info = into_rstest_info(&item_fn);
12071188
let tokens = render_parametrize_cases(item_fn.clone(), info);
12081189

12091190
let output = TestsGroup::from(tokens);
@@ -1247,7 +1228,7 @@ mod render {
12471228
let item_fn = parse_str::<ItemFn>(
12481229
r#"fn test(mut fix: String) { println!("user code") }"#
12491230
).unwrap();
1250-
let mut info: RsTestInfo = (&item_fn).into();
1231+
let mut info: RsTestInfo = into_rstest_info(&item_fn);
12511232
info.push_case(TestCase::from(r#"String::from("3")"#));
12521233
(item_fn, info)
12531234
}
@@ -1256,7 +1237,7 @@ mod render {
12561237
let item_fn = parse_str::<ItemFn>(
12571238
r#"fn test(mut fix: String) { println!("user code") }"#
12581239
).unwrap();
1259-
let mut info: RsTestInfo = (&item_fn).into();
1240+
let mut info: RsTestInfo = into_rstest_info(&item_fn);
12601241
info.extend((0..cases).map(|_| TestCase::from(r#"String::from("3")"#)));
12611242
(item_fn, info)
12621243
}
@@ -1338,39 +1319,34 @@ mod render {
13381319
mod matrix_cases {
13391320
use unindent::Unindent;
13401321

1341-
use crate::parse::matrix::{MatrixData, MatrixInfo, ValueList};
1342-
13431322
/// Should test matrix tests render without take in account MatrixInfo to RsTestInfo
1344-
/// transformation
1323+
/// transformation
13451324
13461325
use super::{*, assert_eq};
1347-
1348-
impl<'a> From<&'a ItemFn> for MatrixData {
1349-
fn from(item_fn: &'a ItemFn) -> Self {
1350-
MatrixData {
1351-
items: fn_args_idents(item_fn)
1352-
.cloned()
1353-
.map(|it|
1354-
ValueList { arg: it, values: vec![] }.into()
1355-
)
1356-
.collect()
1357-
}
1326+
use crate::parse::vlist::ValueList;
1327+
1328+
fn into_rstest_data(item_fn: &ItemFn) -> RsTestData {
1329+
RsTestData {
1330+
items: fn_args_idents(item_fn)
1331+
.cloned()
1332+
.map(|it|
1333+
ValueList { arg: it, values: vec![] }.into()
1334+
)
1335+
.collect(),
13581336
}
13591337
}
13601338

1361-
impl<'a> From<&'a ItemFn> for MatrixInfo {
1362-
fn from(item_fn: &'a ItemFn) -> Self {
1363-
MatrixInfo {
1364-
args: item_fn.into(),
1365-
attributes: Default::default(),
1366-
}
1339+
fn into_rstest_info(item_fn: &ItemFn) -> RsTestInfo {
1340+
RsTestInfo {
1341+
data: into_rstest_data(item_fn),
1342+
attributes: Default::default(),
13671343
}
13681344
}
13691345

13701346
#[test]
13711347
fn should_create_a_module_named_as_test_function() {
13721348
let item_fn = parse_str::<ItemFn>("fn should_be_the_module_name(mut fix: String) {}").unwrap();
1373-
let info = (&item_fn).into();
1349+
let info = into_rstest_info(&item_fn);
13741350
let tokens = render_matrix_cases(item_fn.clone(), info);
13751351

13761352
let output = TestsGroup::from(tokens);
@@ -1383,7 +1359,7 @@ mod render {
13831359
let item_fn = parse_str::<ItemFn>(
13841360
r#"fn should_be_the_module_name(mut fix: String) { println!("user code") }"#
13851361
).unwrap();
1386-
let info = (&item_fn).into();
1362+
let info = into_rstest_info(&item_fn);
13871363
let tokens = render_matrix_cases(item_fn.clone(), info);
13881364

13891365
let mut output = TestsGroup::from(tokens);
@@ -1397,7 +1373,7 @@ mod render {
13971373
let item_fn = parse_str::<ItemFn>(
13981374
r#"fn should_be_the_module_name(mut fix: String) { println!("user code") }"#
13991375
).unwrap();
1400-
let info = (&item_fn).into();
1376+
let info = into_rstest_info(&item_fn);
14011377
let tokens = render_matrix_cases(item_fn.clone(), info);
14021378

14031379
let output = TestsGroup::from(tokens);
@@ -1415,7 +1391,7 @@ mod render {
14151391
let item_fn = parse_str::<ItemFn>(
14161392
r#"fn should_be_the_module_name(mut fix: String) { println!("user code") }"#
14171393
).unwrap();
1418-
let info = (&item_fn).into();
1394+
let info = into_rstest_info(&item_fn);
14191395
let tokens = render_matrix_cases(item_fn.clone(), info);
14201396

14211397
let output = TestsGroup::from(tokens);
@@ -1428,12 +1404,12 @@ mod render {
14281404
assert_eq!(expected, output.module.attrs);
14291405
}
14301406

1431-
fn one_simple_case() -> (ItemFn, MatrixInfo) {
1407+
fn one_simple_case() -> (ItemFn, RsTestInfo) {
14321408
let item_fn = parse_str::<ItemFn>(
14331409
r#"fn test(mut fix: String) { println!("user code") }"#
14341410
).unwrap();
1435-
let info = MatrixInfo {
1436-
args: MatrixData {
1411+
let info = RsTestInfo {
1412+
data: RsTestData {
14371413
items: vec![
14381414
ValueList { arg: ident("fix"), values: vec![expr(r#""value""#)] }.into()
14391415
]
@@ -1460,8 +1436,8 @@ mod render {
14601436
let item_fn = parse_str::<ItemFn>(
14611437
r#"fn test(first: u32, second: u32, third: u32) { println!("user code") }"#
14621438
).unwrap();
1463-
let info = MatrixInfo {
1464-
args: MatrixData {
1439+
let info = RsTestInfo {
1440+
data: RsTestData {
14651441
items: vec![
14661442
values_list("first", ["1", "2"].as_ref()).into(),
14671443
values_list("second", ["3", "4"].as_ref()).into(),
@@ -1498,8 +1474,8 @@ mod render {
14981474
r#"fn test(first: u32, second: u32, third: u32) { println!("user code") }"#
14991475
).unwrap();
15001476
let values = (1..=100).map(|i| i.to_string()).collect::<Vec<_>>();
1501-
let info = MatrixInfo {
1502-
args: MatrixData {
1477+
let info = RsTestInfo {
1478+
data: RsTestData {
15031479
items: vec![
15041480
values_list("first", values.as_ref()).into(),
15051481
values_list("second", values[..10].as_ref()).into(),

0 commit comments

Comments
 (0)