From da8927c6ec7bc8195f67cc1bcce5b84cab52985a Mon Sep 17 00:00:00 2001 From: Kezhu Wang Date: Fri, 19 Apr 2024 16:06:01 +0800 Subject: [PATCH] fix: append `#[::core::prelude::v1::test]` only if it does not exist This way if preceding test macros add `#[::core::prelude::v1::test]` by appending, then we can avoid duplicated test runs. See also frondeus/test-case#101, frondeus/test-case#143 Closes #35. --- Cargo.toml | 4 ++++ macros/src/lib.rs | 24 +++++++++++++++++------- tests/mod.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5ad7a68..7ee333d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,3 +70,7 @@ tracing = {version = "0.1.20"} # # Probably fixed by https://github.com/rust-lang-nursery/lazy-static.rs/pull/107. _lazy_static_unused = { package = "lazy_static", version = "1.0.2" } + +[patch.crates-io] +test-case = { git = "https://github.com/kezhuw/test-case.git", branch = "test-proc-macros-cooperation" } +tokio = { git = "https://github.com/kezhuw/tokio.git", branch = "test-proc-macros-cooperation" } diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 6d29b75..8cad2ca 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -10,6 +10,7 @@ use quote::quote; use syn::parse::Parse; use syn::parse_macro_input; +use syn::parse_quote; use syn::Attribute; use syn::Expr; use syn::ItemFn; @@ -44,12 +45,6 @@ fn parse_attrs(attrs: Vec) -> syn::Result<(AttributeArgs, Vec syn::Result { - let inner_test = if attr.is_empty() { - quote! { ::core::prelude::v1::test } - } else { - attr.into() - }; - let ItemFn { attrs, vis, @@ -61,9 +56,24 @@ fn try_test(attr: TokenStream, input: ItemFn) -> syn::Result { let logging_init = expand_logging_init(&attribute_args); let tracing_init = expand_tracing_init(&attribute_args); + let (inner_test, generated_test) = if attr.is_empty() { + let test_attr: syn::Attribute = parse_quote! { #[::core::prelude::v1::test] }; + let has_test = ignored_attrs.iter().any(|attr| *attr == test_attr); + let generated_test = if has_test { + quote! {} + } else { + quote! { #test_attr } + }; + (quote! {}, generated_test) + } else { + let attr: Tokens = attr.into(); + (quote! { #[#attr] }, quote! {}) + }; + let result = quote! { - #[#inner_test] + #inner_test #(#ignored_attrs)* + #generated_test #vis #sig { // We put all initialization code into a separate module here in // order to prevent potential ambiguities that could result in diff --git a/tests/mod.rs b/tests/mod.rs index 79b0bdc..ffeef3b 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -57,6 +57,36 @@ fn with_inner_test_attribute_and_test_args_and_panic(x: i8, _y: i8) { assert_eq!(x, 0); } +#[tokio::test] +#[test_log::test] +async fn with_append_test_attribute_and_async() { + assert_eq!(async { 42 }.await, 42) +} + +#[test_case::test_case(-2, -4)] +#[test_case::test_case(-2, -5)] +#[test_log::test] +fn with_append_test_attribute_and_test_args(x: i8, _y: i8) { + assert_eq!(x, -2); +} + +#[should_panic] +#[test_case::test_case(-2, -4)] +#[test_case::test_case(-3, -4)] +#[test_log::test] +fn with_append_test_attribute_and_test_args_and_panic(x: i8, _y: i8) { + assert_eq!(x, 0); +} + +#[should_panic] +#[test_case::test_case(-2, -4)] +#[test_case::test_case(-3, -4)] +#[tokio::test] +#[test_log::test] +async fn with_append_test_attribute_and_test_args_and_panic_async(x: i8, _y: i8) { + assert_eq!(x, 0); +} + #[instrument] async fn instrumented(input: usize) -> usize { info!("input = {}", input);