From ad4706472650ab499caeccf5e977cf30fbcb9649 Mon Sep 17 00:00:00 2001 From: Kezhu Wang Date: Tue, 1 Apr 2025 12:58:29 +0800 Subject: [PATCH 1/2] Append generated test macro so next test macros are aware of it This is an attempt to improve capabilities among test macros to avoid duplicated test runs which is rare to be aware of. The rationale is simple: procedure of attribute macro see only attributes following it. Macros next to processing macro will not see generated macro if it is generated in-place. So, instead of generating test macro in-place, appending generated test macro will let macros next to processing macro have chance to react, for example, not generate test macro if there is already one. Without the fix, the new test will run twice. See also tokio-rs/tokio#6497, d-e-s-o/test-log#46, frondeus/test-case#143, la10736/rstest#291, google/googletest-rust#561, kezhuw/stuck#53. --- Cargo.toml | 1 + src/proptest_fn.rs | 42 +++++++++++++++++++++++++++++++++++++++--- tests/proptest_fn.rs | 12 ++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4f640c7..c953646 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,4 @@ proptest = "1.6.0" trybuild = "1.0.96" tokio = { version = "1.38.0", features = ["rt-multi-thread"] } anyhow = "1.0.97" +googletest = "0.14.0" diff --git a/src/proptest_fn.rs b/src/proptest_fn.rs index f275c8c..a21a7af 100644 --- a/src/proptest_fn.rs +++ b/src/proptest_fn.rs @@ -4,10 +4,41 @@ use crate::syn_utils::{Arg, Args}; use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens}; use syn::{ - parse2, parse_quote, parse_str, spanned::Spanned, token, Block, Expr, Field, FieldMutability, - FnArg, Ident, ItemFn, LitStr, Pat, Result, ReturnType, Visibility, + parse2, parse_quote, parse_str, spanned::Spanned, token, Attribute, Block, Expr, Field, + FieldMutability, FnArg, Ident, ItemFn, LitStr, Pat, Result, ReturnType, Visibility, }; +// Check whether given attribute is a test attribute of forms: +// * `#[test]` +// * `#[core::prelude::*::test]` or `#[::core::prelude::*::test]` +// * `#[std::prelude::*::test]` or `#[::std::prelude::*::test]` +fn is_test_attribute(attr: &Attribute) -> bool { + let path = match &attr.meta { + syn::Meta::Path(path) => path, + _ => return false, + }; + const CANDIDATES_LEN: usize = 4; + + let candidates: [[&str; CANDIDATES_LEN]; 2] = [ + ["core", "prelude", "*", "test"], + ["std", "prelude", "*", "test"], + ]; + if path.leading_colon.is_none() + && path.segments.len() == 1 + && path.segments[0].arguments.is_none() + && path.segments[0].ident == "test" + { + return true; + } else if path.segments.len() != candidates[0].len() { + return false; + } + candidates.into_iter().any(|segments| { + path.segments.iter().zip(segments).all(|(segment, path)| { + segment.arguments.is_none() && (path == "*" || segment.ident == path) + }) + }) +} + pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result { let mut attr_args = None; if !attr.is_empty() { @@ -64,6 +95,12 @@ pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result Result anyhow::Result< yield_now().await; anyhow::bail!("error"); } + +#[proptest] +#[gtest] +fn googletest_result(#[strategy(1..10u8)] x: u8) -> googletest::Result<()> { + expect_that!(x, ge(1)); + verify_that!(x, lt(10)) +} From c59f20e5d7ff162470d10fa58c8d3c7d00dee0cc Mon Sep 17 00:00:00 2001 From: frozenlib Date: Tue, 1 Apr 2025 17:41:42 +0900 Subject: [PATCH 2/2] Update dependencies. --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c953646..43eb218 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,14 +18,14 @@ rust-version = "1.70.0" proc-macro = true [dependencies] -syn = { version = "2.0.68", features = ["visit", "full", "extra-traits"] } -quote = "1.0.36" -proc-macro2 = "1.0.86" +syn = { version = "2.0.100", features = ["visit", "full", "extra-traits"] } +quote = "1.0.40" +proc-macro2 = "1.0.94" structmeta = "0.3.0" [dev-dependencies] proptest = "1.6.0" -trybuild = "1.0.96" -tokio = { version = "1.38.0", features = ["rt-multi-thread"] } +trybuild = "1.0.104" +tokio = { version = "1.44.1", features = ["rt-multi-thread"] } anyhow = "1.0.97" googletest = "0.14.0"