Skip to content

Commit

Permalink
Add #[await_future] attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
blastrock committed Dec 1, 2022
1 parent 12b92bb commit 4c5814d
Show file tree
Hide file tree
Showing 14 changed files with 481 additions and 67 deletions.
8 changes: 8 additions & 0 deletions rstest/tests/fixture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,21 @@ mod should {
TestResults::new()
.ok("default_is_async")
.ok("use_async_fixture")
.ok("use_async_fixture_await")
.ok("use_async_impl_output")
.ok("use_async_impl_output_await")
.ok("use_async_nest_fixture_default")
.ok("use_async_nest_fixture_default_await")
.ok("use_async_nest_fixture_injected")
.ok("use_async_nest_fixture_injected_await")
.ok("use_async_nest_fixture_with_default")
.ok("use_async_nest_fixture_with_default_await")
.ok("use_two_args_mix_fixture")
.ok("use_two_args_mix_fixture_await")
.ok("use_two_args_mix_fixture_inject_first")
.ok("use_two_args_mix_fixture_inject_first_await")
.ok("use_two_args_mix_fixture_inject_both")
.ok("use_two_args_mix_fixture_inject_both_await")
.assert(output);
}

Expand Down
63 changes: 62 additions & 1 deletion rstest/tests/resources/fixture/async_fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,21 @@ async fn nest_fixture(#[future] async_u32: u32) -> u32 {
async_u32.await
}

#[fixture]
async fn nest_fixture_await(#[await_future] async_u32: u32) -> u32 {
async_u32
}

#[fixture(fortytwo = async { 42 })]
async fn nest_fixture_with_default(#[future] fortytwo: u32) -> u32 {
fortytwo.await
}

#[fixture(fortytwo = async { 42 })]
async fn nest_fixture_with_default_await(#[await_future] fortytwo: u32) -> u32 {
fortytwo
}

#[rstest]
async fn default_is_async() {
assert_eq!(42, async_u32::default().await);
Expand All @@ -27,21 +37,43 @@ async fn use_async_nest_fixture_default(#[future] nest_fixture: u32) {
assert_eq!(42, nest_fixture.await);
}

#[rstest]
async fn use_async_nest_fixture_default_await(#[await_future] nest_fixture_await: u32) {
assert_eq!(42, nest_fixture_await);
}

#[rstest(nest_fixture(async { 24 }))]
async fn use_async_nest_fixture_injected(#[future] nest_fixture: u32) {
assert_eq!(24, nest_fixture.await);
}

#[rstest(nest_fixture_await(async { 24 }))]
async fn use_async_nest_fixture_injected_await(#[await_future] nest_fixture_await: u32) {
assert_eq!(24, nest_fixture_await);
}

#[rstest]
async fn use_async_nest_fixture_with_default(#[future] nest_fixture_with_default: u32) {
assert_eq!(42, nest_fixture_with_default.await);
}

#[rstest]
async fn use_async_nest_fixture_with_default_await(
#[await_future] nest_fixture_with_default_await: u32,
) {
assert_eq!(42, nest_fixture_with_default_await);
}

#[rstest]
async fn use_async_fixture(#[future] async_u32: u32) {
assert_eq!(42, async_u32.await);
}

#[rstest]
async fn use_async_fixture_await(#[await_future] async_u32: u32) {
assert_eq!(42, async_u32);
}

#[fixture]
async fn async_impl_output() -> impl Read {
std::io::Cursor::new(vec![1, 2, 3, 4, 5])
Expand All @@ -52,22 +84,51 @@ async fn use_async_impl_output<T: Read>(#[future] async_impl_output: T) {
let reader = async_impl_output.await;
}

#[rstest]
async fn use_async_impl_output_await<T: Read>(#[await_future] async_impl_output: T) {
let reader = async_impl_output;
}

#[fixture(four = async { 4 }, two = 2)]
async fn two_args_mix_fixture(#[future] four: u32, two: u32) -> u32 {
four.await * 10 + two
}

#[fixture(four = async { 4 }, two = 2)]
async fn two_args_mix_fixture_await(#[await_future] four: u32, two: u32) -> u32 {
four * 10 + two
}

#[rstest]
async fn use_two_args_mix_fixture(#[future] two_args_mix_fixture: u32) {
assert_eq!(42, two_args_mix_fixture.await);
}

#[rstest]
async fn use_two_args_mix_fixture_await(#[await_future] two_args_mix_fixture_await: u32) {
assert_eq!(42, two_args_mix_fixture_await);
}

#[rstest(two_args_mix_fixture(async { 5 }))]
async fn use_two_args_mix_fixture_inject_first(#[future] two_args_mix_fixture: u32) {
assert_eq!(52, two_args_mix_fixture.await);
}

#[rstest(two_args_mix_fixture_await(async { 5 }))]
async fn use_two_args_mix_fixture_inject_first_await(
#[await_future] two_args_mix_fixture_await: u32,
) {
assert_eq!(52, two_args_mix_fixture_await);
}

#[rstest(two_args_mix_fixture(async { 3 }, 1))]
async fn use_two_args_mix_fixture_inject_both(#[future] two_args_mix_fixture: u32) {
assert_eq!(31, two_args_mix_fixture.await);
}
}

#[rstest(two_args_mix_fixture_await(async { 3 }, 1))]
async fn use_two_args_mix_fixture_inject_both_await(
#[await_future] two_args_mix_fixture_await: u32,
) {
assert_eq!(31, two_args_mix_fixture_await);
}
43 changes: 40 additions & 3 deletions rstest/tests/resources/rstest/cases/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,49 @@ use rstest::*;
#[case::pass_panic(42, async { 41 })]
#[should_panic]
#[case::fail_panic(42, async { 42 })]
async fn my_async_test(#[case] expected: u32, #[case] #[future] value: u32) {
async fn my_async_test(
#[case] expected: u32,
#[case]
#[future]
value: u32,
) {
assert_eq!(expected, value.await);
}

#[rstest]
#[case::pass(42, async { 42 })]
async fn my_async_test_revert(#[case] expected: u32, #[future] #[case] value: u32) {
#[case::fail(42, async { 41 })]
#[should_panic]
#[case::pass_panic(42, async { 41 })]
#[should_panic]
#[case::fail_panic(42, async { 42 })]
async fn my_async_test_await(
#[case] expected: u32,
#[case]
#[await_future]
value: u32,
) {
assert_eq!(expected, value);
}

#[rstest]
#[case::pass(42, async { 42 })]
async fn my_async_test_revert(
#[case] expected: u32,
#[future]
#[case]
value: u32,
) {
assert_eq!(expected, value.await);
}
}

#[rstest]
#[case::pass(42, async { 42 })]
async fn my_async_test_revert_await(
#[case] expected: u32,
#[await_future]
#[case]
value: u32,
) {
assert_eq!(expected, value);
}
21 changes: 15 additions & 6 deletions rstest/tests/resources/rstest/matrix/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@ use rstest::*;

#[rstest]
async fn my_async_test(
#[future]
#[values(async { 1 }, async { 2 })]
first: u32,
#[values(42, 21)]
second: u32
#[future]
#[values(async { 1 }, async { 2 })]
first: u32,
#[values(42, 21)] second: u32,
) {
assert_eq!(42, first.await * second);
}
}

#[rstest]
async fn my_async_test_await(
#[await_future]
#[values(async { 1 }, async { 2 })]
first: u32,
#[values(42, 21)] second: u32,
) {
assert_eq!(42, first * second);
}
9 changes: 9 additions & 0 deletions rstest/tests/rstest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,12 @@ mod cases {
.fail("my_async_test::case_2_fail")
.ok("my_async_test::case_3_pass_panic")
.fail("my_async_test::case_4_fail_panic")
.ok("my_async_test_await::case_1_pass")
.fail("my_async_test_await::case_2_fail")
.ok("my_async_test_await::case_3_pass_panic")
.fail("my_async_test_await::case_4_fail_panic")
.ok("my_async_test_revert::case_1_pass")
.ok("my_async_test_revert_await::case_1_pass")
.assert(output);
}

Expand Down Expand Up @@ -781,6 +786,10 @@ mod matrix {
.fail("my_async_test::first_1")
.fail("my_async_test::first_2")
.ok("my_async_test::first_2")
.ok("my_async_test_await::first_1")
.fail("my_async_test_await::first_1")
.fail("my_async_test_await::first_2")
.ok("my_async_test_await::first_2")
.assert(output);
}

Expand Down
47 changes: 36 additions & 11 deletions rstest_macros/src/parse/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use syn::{
parse::{Parse, ParseStream},
parse_quote,
visit_mut::VisitMut,
Expr, FnArg, Ident, ItemFn, Token,
Expr, FnArg, Ident, ItemFn, Signature, Token,
};

use super::{
extract_argument_attrs, extract_default_return_type, extract_defaults, extract_fixtures,
extract_partials_return_type, parse_vector_trailing_till_double_comma, Attributes,
ExtendWithFunctionAttrs, Fixture,
extract_argument_attrs, extract_awaits, extract_default_return_type, extract_defaults,
extract_fixtures, extract_partials_return_type, parse_vector_trailing_till_double_comma,
Attributes, ExtendWithFunctionAttrs, Fixture,
};
use crate::{
error::ErrorsVec,
Expand All @@ -21,10 +21,23 @@ use crate::{parse::Attribute, utils::attr_in};
use proc_macro2::TokenStream;
use quote::{format_ident, ToTokens};

#[derive(PartialEq, Debug, Default)]
#[derive(PartialEq, Debug)]
pub(crate) struct FixtureInfo {
pub(crate) data: FixtureData,
pub(crate) attributes: FixtureModifiers,
pub(crate) signature_with_future_impls: Signature,
pub(crate) await_args: Vec<Ident>,
}

impl Default for FixtureInfo {
fn default() -> Self {
Self {
data: Default::default(),
attributes: Default::default(),
signature_with_future_impls: parse_quote! { fn f() },
await_args: Default::default(),
}
}
}

impl Parse for FixtureModifiers {
Expand All @@ -44,6 +57,7 @@ impl Parse for FixtureInfo {
.parse::<Token![::]>()
.or_else(|_| Ok(Default::default()))
.and_then(|_| input.parse())?,
..Default::default()
}
})
}
Expand All @@ -59,20 +73,25 @@ impl ExtendWithFunctionAttrs for FixtureInfo {
defaults,
default_return_type,
partials_return_type,
once
once,
awaits
) = merge_errors!(
extract_fixtures(item_fn),
extract_defaults(item_fn),
extract_default_return_type(item_fn),
extract_partials_return_type(item_fn),
extract_once(item_fn)
extract_once(item_fn),
// Keep this last so that it works on the final signature, without attributes
extract_awaits(item_fn)
)?;
self.data.items.extend(
fixtures
.into_iter()
.map(|f| f.into())
.chain(defaults.into_iter().map(|d| d.into())),
);
self.signature_with_future_impls = awaits.signature_with_future_impls;
self.await_args = awaits.await_args;
if let Some(return_type) = default_return_type {
self.attributes.set_default_return_type(return_type);
}
Expand Down Expand Up @@ -352,6 +371,8 @@ mod should {
],
}
.into(),
signature_with_future_impls: parse_quote! {fn f()},
await_args: vec![],
};

assert_eq!(expected, data);
Expand Down Expand Up @@ -438,6 +459,7 @@ mod extend {
fixture("f2", &["vec![1,2]", r#""s""#]).into(),
]
.into(),
signature_with_future_impls: item_fn.sig.clone(),
..Default::default()
};

Expand All @@ -447,18 +469,18 @@ mod extend {

#[test]
fn rename_with_attributes() {
let mut item_fn = r#"
let mut item_fn: ItemFn = r#"
fn test_fn(
#[from(long_fixture_name)]
#[with(42, "other")] short: u32,
#[from(long_fixture_name)]
#[with(42, "other")] short: u32,
#[from(simple)]
s: &str,
no_change: i32) {
}
"#
.ast();

let expected = FixtureInfo {
let mut expected = FixtureInfo {
data: vec![
fixture("short", &["42", r#""other""#])
.with_resolve("long_fixture_name")
Expand All @@ -472,6 +494,8 @@ mod extend {
let mut data = FixtureInfo::default();
data.extend_with_function_attrs(&mut item_fn).unwrap();

expected.signature_with_future_impls = item_fn.sig.clone();

assert_eq!(expected, data);
}

Expand All @@ -492,6 +516,7 @@ mod extend {
arg_value("f2", r#"(vec![1,2], "s")"#).into(),
]
.into(),
signature_with_future_impls: item_fn.sig.clone(),
..Default::default()
};

Expand Down

0 comments on commit 4c5814d

Please sign in to comment.