1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemFn};
4
5#[proc_macro_attribute]
6pub fn test(_: TokenStream, item: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(item as ItemFn);
8 let test_name = input.sig.ident.clone();
9 let test_arguments = input.sig.inputs;
10 let test_block = input.block;
11 let inner_test_name = syn::Ident::new(
12 format!("inner_{}", test_name).as_str(),
13 input.sig.ident.span(),
14 );
15
16 let setup = quote! {
17 let context = common::setup().await;
18 };
19
20 let teardown = quote! {
21 teardown(context).await;
22 };
23
24 let output = quote!(
25 #[::tokio::test]
26 async fn #test_name() {
27 #setup
28 async fn #inner_test_name(#test_arguments) #test_block
29 #inner_test_name(&context).await;
30 #teardown
31 }
32 );
33
34 TokenStream::from(output)
35}