1use proc_macro::{TokenStream, TokenTree};
2use quote::quote;
3
4#[proc_macro_attribute]
7pub fn unit_test(_args: TokenStream, input: TokenStream) -> TokenStream {
8 let mut output: TokenStream = quote! {
9 #[test]
10 #[cfg_attr(not(feature = "unit-test"), ignore)]
11 }
12 .into();
13 output.extend(input.into_iter());
14 output
15}
16
17#[proc_macro_attribute]
18pub fn integration_test(_args: TokenStream, input: TokenStream) -> TokenStream {
19 let mut output: TokenStream = quote! {
20 #[test]
21 #[cfg_attr(not(feature = "integration-test"), ignore)]
22 }
23 .into();
24 output.extend(input.into_iter());
25 output
26}
27
28#[proc_macro_attribute]
29pub fn system_test(_args: TokenStream, input: TokenStream) -> TokenStream {
30 let mut output: TokenStream = quote! {
31 #[test]
32 #[cfg_attr(not(feature = "system-test"), ignore)]
33 }
34 .into();
35 output.extend(input.into_iter());
36 output
37}
38
39#[proc_macro_attribute]
40pub fn tokio_unit_test(_args: TokenStream, input: TokenStream) -> TokenStream {
41 let mut output: TokenStream = quote! {
42 #[tokio::test]
43 #[cfg_attr(not(feature = "unit-test"), ignore)]
44 }
45 .into();
46 output.extend(input.into_iter());
47 output
48}
49
50#[proc_macro_attribute]
51pub fn tokio_integration_test(_args: TokenStream, input: TokenStream) -> TokenStream {
52 let mut output: TokenStream = quote! {
53 #[tokio::test]
54 #[cfg_attr(not(feature = "integration-test"), ignore)]
55 }
56 .into();
57 output.extend(input.into_iter());
58 output
59}
60
61#[proc_macro_attribute]
62pub fn tokio_system_test(_args: TokenStream, input: TokenStream) -> TokenStream {
63 let mut output: TokenStream = quote! {
64 #[tokio::test]
65 #[cfg_attr(not(feature = "system-test"), ignore)]
66 }
67 .into();
68 output.extend(input.into_iter());
69 output
70}
71
72fn partition_at_first_ident(input: TokenStream) -> (TokenStream, TokenStream) {
73 let mut left = TokenStream::new();
74 let mut right = TokenStream::new();
75 let mut input = input.into_iter();
76 for token_tree in input.by_ref() {
77 match token_tree {
78 TokenTree::Ident(_) => {
79 right.extend(TokenStream::from(token_tree));
80 break;
81 }
82 _ => {
83 left.extend(TokenStream::from(token_tree));
84 }
85 }
86 }
87 right.extend(input);
88 (left, right)
89}
90
91#[proc_macro_attribute]
92pub fn tokio_unit_rstest(_args: TokenStream, input: TokenStream) -> TokenStream {
93 let (left, right) = partition_at_first_ident(input);
94 let mut output: TokenStream = quote! {
95 #[rstest]
96 }
97 .into();
98 let center: TokenStream = quote! {
99 #[tokio::test]
100 #[cfg_attr(not(feature = "unit-test"), ignore)]
101 }
102 .into();
103 output.extend(left);
104 output.extend(center);
105 output.extend(right);
106 output
107}
108
109#[proc_macro_attribute]
110pub fn unit_rstest(_args: TokenStream, input: TokenStream) -> TokenStream {
111 let (left, right) = partition_at_first_ident(input);
112 let mut output: TokenStream = quote! {
113 #[rstest]
114 }
115 .into();
116 let center: TokenStream = quote! {
117 #[cfg_attr(not(feature = "unit-test"), ignore)]
118 }
119 .into();
120 output.extend(left);
121 output.extend(center);
122 output.extend(right);
123 output
124}