Skip to content

Commit 454df84

Browse files
authored
feat: support outer doc comments for naming matrix tests (#321)
Adds support for using outer doc comments (`///`) instead of auto-generated tests names for parameterized matrix tests. e.g. legacy compact syntax: ```rust expected => [ /// forty_two 42, /// four 2*3-2, ], )] fn test(expected: usize) { ... } ``` e.g. attribute syntax: ```rust fn test( #[values( /// forty_two 42, /// four 2*3-2, )] expected: usize, ) { ... } ``` The generated test names will be `values_1_len_forty_two` and `values_2_len_four`. Fixes <#320> Signed-off-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
1 parent ff20f9a commit 454df84

File tree

9 files changed

+297
-15
lines changed

9 files changed

+297
-15
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
### Add
1111

12+
- Doc comments before `#[values(...)]` entries can be used to override the generated matrix
13+
test names (both for the legacy `arg => [..]` syntax and the new attribute form).
14+
See [#321](https://github.com/la10736/rstest/pull/321) thanks to @orhun.
15+
1216
### Fixed
1317

1418
- Fix compilation under bazel by upgrading proc-macro-crate to 3.4.0

rstest/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,28 @@ pub use rstest_macros::fixture;
938938
/// Note that the test names contains the given expression sanitized into
939939
/// a valid Rust identifier name. This should help to identify which case fails.
940940
///
941+
/// If you prefer to provide an explicit name you can use doc comments before
942+
/// each value inside the `#[values(...)]` attribute:
943+
///
944+
/// ```
945+
/// # use rstest::rstest;
946+
/// #[rstest]
947+
/// fn describe_values(
948+
/// #[values(
949+
/// /// short_value
950+
/// 42,
951+
/// /// long_value
952+
/// 100,
953+
/// )]
954+
/// value: u32,
955+
/// ) {
956+
/// assert!(value > 0);
957+
/// }
958+
/// ```
959+
///
960+
/// The generated tests will be named `value_1_short_value` and
961+
/// `value_2_long_value` instead of using the raw expression text.
962+
///
941963
///
942964
/// Also value list implements the magic conversion feature: every time the value type
943965
/// implements `FromStr` trait you can use a literal string to define it.

rstest/tests/resources/rstest/matrix/simple.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,21 @@ use rstest::rstest;
77
fn strlen_test(expected: usize, input: &str) {
88
assert_eq!(expected, input.len());
99
}
10+
11+
#[rstest(
12+
expected => [
13+
/// len_four
14+
4,
15+
/// len_four_alt
16+
2*3-2,
17+
],
18+
input => [
19+
/// greet_ciao
20+
"ciao",
21+
/// greet_buzz
22+
"buzz",
23+
],
24+
)]
25+
fn doc_comment_strlen_test(expected: usize, input: &str) {
26+
assert_eq!(expected, input.len());
27+
}

rstest/tests/resources/rstest/matrix/use_attr.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,65 @@ fn first(#[values(4, 2*3-2)] expected: usize, input: &str) {
1818
fn second(expected: usize, #[values("ciao", "buzz")] input: &str) {
1919
assert_eq!(expected, input.len());
2020
}
21+
22+
#[rstest]
23+
fn doc_comment_both(
24+
#[values(
25+
/// len_four
26+
4,
27+
/// len_four_alt
28+
2*3-2
29+
)]
30+
expected: usize,
31+
#[values(
32+
/// greet_ciao
33+
"ciao",
34+
/// greet_buzz
35+
"buzz"
36+
)]
37+
input: &str,
38+
) {
39+
assert_eq!(expected, input.len());
40+
}
41+
42+
#[rstest(
43+
input => [
44+
/// greet_ciao
45+
"ciao",
46+
/// greet_buzz
47+
"buzz",
48+
]
49+
)]
50+
fn doc_comment_first(
51+
#[values(
52+
/// len_four
53+
4,
54+
/// len_four_alt
55+
2*3-2
56+
)]
57+
expected: usize,
58+
input: &str,
59+
) {
60+
assert_eq!(expected, input.len());
61+
}
62+
63+
#[rstest(
64+
expected => [
65+
/// len_four
66+
4,
67+
/// len_four_alt
68+
2*3-2,
69+
]
70+
)]
71+
fn doc_comment_second(
72+
expected: usize,
73+
#[values(
74+
/// greet_ciao
75+
"ciao",
76+
/// greet_buzz
77+
"buzz"
78+
)]
79+
input: &str,
80+
) {
81+
assert_eq!(expected, input.len());
82+
}

rstest/tests/rstest/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,10 @@ mod matrix {
907907
.ok("strlen_test::expected_1_4::input_2___buzz__")
908908
.ok("strlen_test::expected_2_2_3_2::input_1___ciao__")
909909
.ok("strlen_test::expected_2_2_3_2::input_2___buzz__")
910+
.ok("doc_comment_strlen_test::expected_1_len_four::input_1_greet_ciao")
911+
.ok("doc_comment_strlen_test::expected_1_len_four::input_2_greet_buzz")
912+
.ok("doc_comment_strlen_test::expected_2_len_four_alt::input_1_greet_ciao")
913+
.ok("doc_comment_strlen_test::expected_2_len_four_alt::input_2_greet_buzz")
910914
.assert(output);
911915
}
912916

@@ -998,6 +1002,18 @@ mod matrix {
9981002
.ok("second::expected_1_4::input_2___buzz__")
9991003
.ok("second::expected_2_2_3_2::input_1___ciao__")
10001004
.ok("second::expected_2_2_3_2::input_2___buzz__")
1005+
.ok("doc_comment_both::expected_1_len_four::input_1_greet_ciao")
1006+
.ok("doc_comment_both::expected_1_len_four::input_2_greet_buzz")
1007+
.ok("doc_comment_both::expected_2_len_four_alt::input_1_greet_ciao")
1008+
.ok("doc_comment_both::expected_2_len_four_alt::input_2_greet_buzz")
1009+
.ok("doc_comment_first::input_1_greet_ciao::expected_1_len_four")
1010+
.ok("doc_comment_first::input_2_greet_buzz::expected_1_len_four")
1011+
.ok("doc_comment_first::input_1_greet_ciao::expected_2_len_four_alt")
1012+
.ok("doc_comment_first::input_2_greet_buzz::expected_2_len_four_alt")
1013+
.ok("doc_comment_second::expected_1_len_four::input_1_greet_ciao")
1014+
.ok("doc_comment_second::expected_1_len_four::input_2_greet_buzz")
1015+
.ok("doc_comment_second::expected_2_len_four_alt::input_1_greet_ciao")
1016+
.ok("doc_comment_second::expected_2_len_four_alt::input_2_greet_buzz")
10011017
.assert(output);
10021018
}
10031019
}

rstest_macros/src/parse/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use quote::ToTokens;
1919
use testcase::TestCase;
2020

2121
use self::{
22-
expressions::Expressions, just_once::JustOnceFnArgAttributeExtractor, vlist::ValueList,
22+
expressions::Expressions,
23+
just_once::JustOnceFnArgAttributeExtractor,
24+
vlist::{MatrixValues, ValueList},
2325
};
2426

2527
// To use the macros this should be the first one module
@@ -363,10 +365,11 @@ impl VisitMut for CasesFunctionExtractor {
363365
if attr_starts_with(&attr, &case) {
364366
match attr.parse_args::<Expressions>() {
365367
Ok(expressions) => {
368+
let args = expressions.take();
366369
let description =
367370
attr.path().segments.iter().nth(1).map(|p| p.ident.clone());
368371
self.0.push(TestCase {
369-
args: expressions.into(),
372+
args,
370373
attrs: std::mem::take(&mut attrs_buffer),
371374
description,
372375
});
@@ -398,9 +401,9 @@ pub(crate) fn extract_value_list(item_fn: &mut ItemFn) -> Result<Vec<ValueList>,
398401
type Out = ValueList;
399402

400403
fn build(attr: syn::Attribute, extra: &Pat) -> syn::Result<Self::Out> {
401-
attr.parse_args::<Expressions>().map(|v| ValueList {
404+
attr.parse_args::<MatrixValues>().map(|v| ValueList {
402405
arg: extra.clone(),
403-
values: v.take().into_iter().map(|e| e.into()).collect(),
406+
values: v.into_values(),
404407
})
405408
}
406409
}

rstest_macros/src/parse/rstest.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,44 @@ mod test {
10571057
&pat("__destruct_2")
10581058
);
10591059
}
1060+
1061+
#[test]
1062+
fn doc_comment_in_values_attribute_used_as_description() {
1063+
let mut item_fn = r#"
1064+
fn test_fn(
1065+
#[values(
1066+
/// the answer
1067+
42,
1068+
/// bigger entry
1069+
100,
1070+
2
1071+
)]
1072+
arg: u32
1073+
) {
1074+
}
1075+
"#
1076+
.ast();
1077+
1078+
let mut info = RsTestInfo::default();
1079+
1080+
info.extend_with_function_attrs(&mut item_fn).unwrap();
1081+
1082+
let list_values = info.data.list_values().cloned().collect::<Vec<_>>();
1083+
1084+
assert_eq!(1, list_values.len());
1085+
let values = &list_values[0].values;
1086+
1087+
assert_eq!(3, values.len());
1088+
1089+
assert_eq!("the_answer", values[0].description());
1090+
assert_eq!("42", values[0].expr.to_token_stream().to_string());
1091+
1092+
assert_eq!("bigger_entry", values[1].description());
1093+
assert_eq!("100", values[1].expr.to_token_stream().to_string());
1094+
1095+
assert_eq!("2", values[2].description());
1096+
assert_eq!("2", values[2].expr.to_token_stream().to_string());
1097+
}
10601098
}
10611099

10621100
#[test]

0 commit comments

Comments
 (0)