use proc_macro::TokenStream;
use quote::quote;
use syn::{ItemFn, parse_macro_input};
#[proc_macro_attribute]
pub fn db_test(_attr: TokenStream, stream: TokenStream) -> TokenStream {
let input = parse_macro_input!(stream as ItemFn);
let ItemFn {
attrs: _,
vis,
sig,
block,
} = input;
let impl_sig = sig.clone();
let fn_name = &sig.ident;
let sqlite_fn_name = quote::format_ident!("sqlite_{fn_name}");
let postgres_fn_name = quote::format_ident!("postgres_{fn_name}");
let _test_impl_name = quote::format_ident!("{fn_name}_impl");
let _stmts = &block.stmts;
let output = quote! {
#[allow(unused)]
#vis #impl_sig #block
#[tokio::test]
#vis async fn #sqlite_fn_name() {
use std::path;
use std::ops::Add;
use kellnr_common::util::generate_rand_string;
let path = path::PathBuf::from("/tmp").join(generate_rand_string(8).add(".db"));
let con_string = kellnr_db::SqliteConString {
path: path.to_owned(),
salt: "salt".to_string(),
admin_pwd: "123".to_string(),
admin_token: "token".to_string(),
session_age: std::time::Duration::from_secs(1),
};
let con_string = kellnr_db::ConString::Sqlite(con_string);
let test_db = kellnr_db::Database::new(&con_string, 10).await.unwrap();
#fn_name(&test_db).await;
rm_rf::remove(&path).expect("Cannot remove test db");
}
#[tokio::test]
#vis async fn #postgres_fn_name() {
use testcontainers::runners::AsyncRunner;
let pg_container = image::Postgres::default().start().await.expect("Failed to start postgres container");
let port = pg_container.get_host_port_ipv4(image::Postgres::PG_PORT).await.expect("Failed to get port");
let admin = kellnr_db::AdminUser::new("123".to_string(), "token".to_string(), "salt".to_string());
let pg_db = kellnr_db::PgConString::new("localhost", port, "kellnr", "admin", "admin", admin);
let pg_db = kellnr_db::ConString::Postgres(pg_db);
let test_db = kellnr_db::Database::new(&pg_db, 10).await.unwrap();
#fn_name(&test_db).await;
}
};
output.into()
}