use super::*;
use darling::FromMeta;
use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::{parse_macro_input, AttributeArgs, ItemFn};
pub fn connector_test_impl(attr: TokenStream, input: TokenStream) -> TokenStream {
let attributes_meta: syn::AttributeArgs = parse_macro_input!(attr as AttributeArgs);
let args = ConnectorTestArgs::from_list(&attributes_meta);
let args = match args {
Ok(args) => args,
Err(err) => return err.write_errors().into(),
};
if let Err(err) = args.validate(false) {
return err.write_errors().into();
};
let excluded_features = args.exclude_features.features();
let db_schemas = args.db_schemas.schemas();
let only = &args.only;
let exclude = &args.exclude;
let handler = args.schema.unwrap().handler_path;
let mut test_function = parse_macro_input!(input as ItemFn);
if test_function.sig.inputs.len() != 1 {
return syn::Error::new_spanned(
test_function.sig,
"connector test functions must take exactly one argument: `runner: Runner`.",
)
.to_compile_error()
.into();
}
if test_function.sig.asyncness.is_none() {
return syn::Error::new_spanned(test_function.sig, "connector test functions must be async")
.to_compile_error()
.into();
}
let test_fn_ident = test_function.sig.ident;
let runner_fn_ident = Ident::new(&format!("run_{test_fn_ident}"), Span::call_site());
test_function.sig.ident = runner_fn_ident.clone();
let test_name = test_fn_ident.to_string();
let suite_name = args.suite.expect("A test must have a test suite.");
let test_database_name = format!("{suite_name}_{test_name}");
let capabilities = args.capabilities.idents;
let referential_override = match args.relation_mode.or(args.referential_integrity) {
Some(ref_override) => {
let wat = ref_override.to_string();
quote! { Some(#wat.to_string()) }
}
None => quote! { None },
};
let test = quote! {
#[test]
fn #test_fn_ident() {
query_tests_setup::run_connector_test(
#test_database_name,
&[#only],
&[#exclude],
enumflags2::make_bitflags!(ConnectorCapability::{#(#capabilities)|*}),
&[#(#excluded_features),*],
#handler,
&[#(#db_schemas),*],
#referential_override,
#runner_fn_ident,
);
}
#test_function
};
test.into()
}