Skip to content

Commit 1b145db

Browse files
authored
Merge pull request #17 from kezhuw/test-proc-macros-cooperation
Append generated test macro so next test macros are aware of it
2 parents b329f56 + c59f20e commit 1b145db

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

Cargo.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ rust-version = "1.70.0"
1818
proc-macro = true
1919

2020
[dependencies]
21-
syn = { version = "2.0.68", features = ["visit", "full", "extra-traits"] }
22-
quote = "1.0.36"
23-
proc-macro2 = "1.0.86"
21+
syn = { version = "2.0.100", features = ["visit", "full", "extra-traits"] }
22+
quote = "1.0.40"
23+
proc-macro2 = "1.0.94"
2424
structmeta = "0.3.0"
2525

2626
[dev-dependencies]
2727
proptest = "1.6.0"
28-
trybuild = "1.0.96"
29-
tokio = { version = "1.38.0", features = ["rt-multi-thread"] }
28+
trybuild = "1.0.104"
29+
tokio = { version = "1.44.1", features = ["rt-multi-thread"] }
3030
anyhow = "1.0.97"
31+
googletest = "0.14.0"

src/proptest_fn.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,41 @@ use crate::syn_utils::{Arg, Args};
44
use proc_macro2::{Span, TokenStream};
55
use quote::{quote, ToTokens};
66
use syn::{
7-
parse2, parse_quote, parse_str, spanned::Spanned, token, Block, Expr, Field, FieldMutability,
8-
FnArg, Ident, ItemFn, LitStr, Pat, Result, ReturnType, Visibility,
7+
parse2, parse_quote, parse_str, spanned::Spanned, token, Attribute, Block, Expr, Field,
8+
FieldMutability, FnArg, Ident, ItemFn, LitStr, Pat, Result, ReturnType, Visibility,
99
};
1010

11+
// Check whether given attribute is a test attribute of forms:
12+
// * `#[test]`
13+
// * `#[core::prelude::*::test]` or `#[::core::prelude::*::test]`
14+
// * `#[std::prelude::*::test]` or `#[::std::prelude::*::test]`
15+
fn is_test_attribute(attr: &Attribute) -> bool {
16+
let path = match &attr.meta {
17+
syn::Meta::Path(path) => path,
18+
_ => return false,
19+
};
20+
const CANDIDATES_LEN: usize = 4;
21+
22+
let candidates: [[&str; CANDIDATES_LEN]; 2] = [
23+
["core", "prelude", "*", "test"],
24+
["std", "prelude", "*", "test"],
25+
];
26+
if path.leading_colon.is_none()
27+
&& path.segments.len() == 1
28+
&& path.segments[0].arguments.is_none()
29+
&& path.segments[0].ident == "test"
30+
{
31+
return true;
32+
} else if path.segments.len() != candidates[0].len() {
33+
return false;
34+
}
35+
candidates.into_iter().any(|segments| {
36+
path.segments.iter().zip(segments).all(|(segment, path)| {
37+
segment.arguments.is_none() && (path == "*" || segment.ident == path)
38+
})
39+
})
40+
}
41+
1142
pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result<TokenStream> {
1243
let mut attr_args = None;
1344
if !attr.is_empty() {
@@ -64,6 +95,12 @@ pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result<TokenStr
6495
};
6596
item_fn.sig.inputs = parse_quote! { input: #args_type_ident };
6697
item_fn.block = Box::new(parse2(block)?);
98+
if !item_fn.attrs.iter().any(is_test_attribute) {
99+
let test_attr: Attribute = parse_quote! {
100+
#[::core::prelude::v1::test]
101+
};
102+
item_fn.attrs.push(test_attr);
103+
}
67104
let args_fields = args.iter().map(|arg| &arg.field);
68105
let config = to_proptest_config(config_args);
69106
let ts = quote! {
@@ -75,7 +112,6 @@ pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result<TokenStr
75112
#[cfg(test)]
76113
proptest::proptest! {
77114
#config
78-
#[test]
79115
#item_fn
80116
}
81117
};

tests/proptest_fn.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ use proptest::{prelude::ProptestConfig, prop_assert};
66
use test_strategy::proptest;
77
use tokio::task::yield_now;
88

9+
use googletest::expect_that;
10+
use googletest::gtest;
11+
use googletest::matchers::*;
12+
use googletest::verify_that;
13+
914
#[proptest]
1015
fn example(_x: u32, #[strategy(1..10u32)] y: u32, #[strategy(0..#y)] z: u32) {
1116
assert!(1 <= y);
@@ -291,3 +296,10 @@ async fn anyhow_result_bail_async(#[strategy(1..10u8)] x: u8) -> anyhow::Result<
291296
yield_now().await;
292297
anyhow::bail!("error");
293298
}
299+
300+
#[proptest]
301+
#[gtest]
302+
fn googletest_result(#[strategy(1..10u8)] x: u8) -> googletest::Result<()> {
303+
expect_that!(x, ge(1));
304+
verify_that!(x, lt(10))
305+
}

0 commit comments

Comments
 (0)