atagen

matrix-rust-sdk

public
Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk.git

Blame: testing/matrix-sdk-test-macros/src/lib.rs

7ff8adafe9e4atagen2026-10-22 12:30 UTC1
use proc_macro::TokenStream;
7ff8adafe9e4atagen2026-10-22 12:30 UTC2
use quote::{ToTokens, format_ident, quote};
7ff8adafe9e4atagen2026-10-22 12:30 UTC3
use syn::parse_macro_input;
7ff8adafe9e4atagen2026-10-22 12:30 UTC4
7ff8adafe9e4atagen2026-10-22 12:30 UTC5
/// Attribute to use `wasm_bindgen_test` for wasm32 targets and `tokio::test`
7ff8adafe9e4atagen2026-10-22 12:30 UTC6
/// for everything else with async-support and custom result-types
7ff8adafe9e4atagen2026-10-22 12:30 UTC7
#[proc_macro_attribute]
7ff8adafe9e4atagen2026-10-22 12:30 UTC8
pub fn async_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
7ff8adafe9e4atagen2026-10-22 12:30 UTC9
    let fun = parse_macro_input!(item as syn::ItemFn);
7ff8adafe9e4atagen2026-10-22 12:30 UTC10
7ff8adafe9e4atagen2026-10-22 12:30 UTC11
    if !fun.sig.ident.to_string().starts_with("test_") {
7ff8adafe9e4atagen2026-10-22 12:30 UTC12
        panic!("test function names must start with test_");
7ff8adafe9e4atagen2026-10-22 12:30 UTC13
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC14
7ff8adafe9e4atagen2026-10-22 12:30 UTC15
    // on the regular return-case, we can just use cfg_attr and quit early
7ff8adafe9e4atagen2026-10-22 12:30 UTC16
    if fun.sig.output == syn::ReturnType::Default {
7ff8adafe9e4atagen2026-10-22 12:30 UTC17
        let attrs = r#"
7ff8adafe9e4atagen2026-10-22 12:30 UTC18
            #[cfg_attr(not(target_family = "wasm"), tokio::test)]
7ff8adafe9e4atagen2026-10-22 12:30 UTC19
            #[cfg_attr(target_family = "wasm", wasm_bindgen_test::wasm_bindgen_test)]
7ff8adafe9e4atagen2026-10-22 12:30 UTC20
        "#;
7ff8adafe9e4atagen2026-10-22 12:30 UTC21
7ff8adafe9e4atagen2026-10-22 12:30 UTC22
        let mut out: TokenStream = attrs.parse().expect("Static works");
7ff8adafe9e4atagen2026-10-22 12:30 UTC23
        let inner: TokenStream = fun.into_token_stream().into();
7ff8adafe9e4atagen2026-10-22 12:30 UTC24
        out.extend(inner);
7ff8adafe9e4atagen2026-10-22 12:30 UTC25
        return out;
7ff8adafe9e4atagen2026-10-22 12:30 UTC26
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC27
7ff8adafe9e4atagen2026-10-22 12:30 UTC28
    // on the more complicated case, where we have some `->`-Result-Arrow
7ff8adafe9e4atagen2026-10-22 12:30 UTC29
    // `wasm_bindgen_test` doesn't yet support
7ff8adafe9e4atagen2026-10-22 12:30 UTC30
    // - see https://github.com/rustwasm/wasm-bindgen/issues/2565 -
7ff8adafe9e4atagen2026-10-22 12:30 UTC31
    // we split the attribution into to functions: one with the original
7ff8adafe9e4atagen2026-10-22 12:30 UTC32
    // to be attributed for non-wasm, and then a second outer-wrapper function
7ff8adafe9e4atagen2026-10-22 12:30 UTC33
    // that calls the first in wasm32 cases.
7ff8adafe9e4atagen2026-10-22 12:30 UTC34
7ff8adafe9e4atagen2026-10-22 12:30 UTC35
    let attrs = r#"
7ff8adafe9e4atagen2026-10-22 12:30 UTC36
        #[cfg_attr(not(target_family = "wasm"), tokio::test)]
7ff8adafe9e4atagen2026-10-22 12:30 UTC37
    "#;
7ff8adafe9e4atagen2026-10-22 12:30 UTC38
7ff8adafe9e4atagen2026-10-22 12:30 UTC39
    let mut out: TokenStream = attrs.parse().expect("Static works.");
7ff8adafe9e4atagen2026-10-22 12:30 UTC40
7ff8adafe9e4atagen2026-10-22 12:30 UTC41
    let mut outer = fun.clone();
7ff8adafe9e4atagen2026-10-22 12:30 UTC42
    let fn_name = fun.sig.ident.clone();
7ff8adafe9e4atagen2026-10-22 12:30 UTC43
    let fn_call: TokenStream = if fun.sig.asyncness.is_some() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC44
        quote! {
7ff8adafe9e4atagen2026-10-22 12:30 UTC45
            {
7ff8adafe9e4atagen2026-10-22 12:30 UTC46
                let res = #fn_name().await;
7ff8adafe9e4atagen2026-10-22 12:30 UTC47
                assert!(res.is_ok(), "{:?}", res);
7ff8adafe9e4atagen2026-10-22 12:30 UTC48
            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC49
        }
7ff8adafe9e4atagen2026-10-22 12:30 UTC50
    } else {
7ff8adafe9e4atagen2026-10-22 12:30 UTC51
        quote! {
7ff8adafe9e4atagen2026-10-22 12:30 UTC52
            {
7ff8adafe9e4atagen2026-10-22 12:30 UTC53
                let res = #fn_name();
7ff8adafe9e4atagen2026-10-22 12:30 UTC54
                assert!(res.is_ok(), "{:?}", res);
7ff8adafe9e4atagen2026-10-22 12:30 UTC55
            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC56
        }
7ff8adafe9e4atagen2026-10-22 12:30 UTC57
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC58
    .into();
7ff8adafe9e4atagen2026-10-22 12:30 UTC59
    outer.sig.output = syn::ReturnType::Default;
7ff8adafe9e4atagen2026-10-22 12:30 UTC60
    outer.sig.ident = format_ident!("{}_outer", fun.sig.ident);
7ff8adafe9e4atagen2026-10-22 12:30 UTC61
    outer.block = Box::new(parse_macro_input!(fn_call as syn::Block));
7ff8adafe9e4atagen2026-10-22 12:30 UTC62
7ff8adafe9e4atagen2026-10-22 12:30 UTC63
    let inner: TokenStream = fun.into_token_stream().into();
7ff8adafe9e4atagen2026-10-22 12:30 UTC64
    out.extend(inner);
7ff8adafe9e4atagen2026-10-22 12:30 UTC65
7ff8adafe9e4atagen2026-10-22 12:30 UTC66
    let attrs = r#"
7ff8adafe9e4atagen2026-10-22 12:30 UTC67
        #[cfg(target_family = "wasm")]
7ff8adafe9e4atagen2026-10-22 12:30 UTC68
        #[wasm_bindgen_test::wasm_bindgen_test]
7ff8adafe9e4atagen2026-10-22 12:30 UTC69
    "#;
7ff8adafe9e4atagen2026-10-22 12:30 UTC70
    let outer_attrs: TokenStream = attrs.parse().expect("Static works.");
7ff8adafe9e4atagen2026-10-22 12:30 UTC71
    let of: TokenStream = outer.into_token_stream().into();
7ff8adafe9e4atagen2026-10-22 12:30 UTC72
    out.extend(outer_attrs);
7ff8adafe9e4atagen2026-10-22 12:30 UTC73
    out.extend(of);
7ff8adafe9e4atagen2026-10-22 12:30 UTC74
7ff8adafe9e4atagen2026-10-22 12:30 UTC75
    out
7ff8adafe9e4atagen2026-10-22 12:30 UTC76
}