@@ -4,10 +4,41 @@ use crate::syn_utils::{Arg, Args};
4
4
use proc_macro2:: { Span , TokenStream } ;
5
5
use quote:: { quote, ToTokens } ;
6
6
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 ,
9
9
} ;
10
10
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
+
11
42
pub fn build_proptest ( attr : TokenStream , mut item_fn : ItemFn ) -> Result < TokenStream > {
12
43
let mut attr_args = None ;
13
44
if !attr. is_empty ( ) {
@@ -64,6 +95,12 @@ pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result<TokenStr
64
95
} ;
65
96
item_fn. sig . inputs = parse_quote ! { input: #args_type_ident } ;
66
97
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
+ }
67
104
let args_fields = args. iter ( ) . map ( |arg| & arg. field ) ;
68
105
let config = to_proptest_config ( config_args) ;
69
106
let ts = quote ! {
@@ -75,7 +112,6 @@ pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result<TokenStr
75
112
#[ cfg( test) ]
76
113
proptest:: proptest! {
77
114
#config
78
- #[ test]
79
115
#item_fn
80
116
}
81
117
} ;
0 commit comments